mko*_*zun 16 java garbage-collection out-of-memory
我的方法是创建十万个本地集合并用随机字符串填充它们,如下所示:
SecureRandom random = new SecureRandom();
for(int i = 0 ; i < 100000 ; i++){
HashMap<String, String> map = new HashMap<String, String>();
for(int j = 0 ; j < 30 ; j++){
map.put(new BigInteger(130, random).toString(32), new BigInteger(130, random).toString(32));
}
}
Run Code Online (Sandbox Code Playgroud)
我也提供了-XX:+ UseGCOverheadLimit jvm参数,但无法获取错误.是否有任何简单可靠的方法/黑客来获取此错误?
kdg*_*ory 10
既然你没有接受任何答案,我会假设他们都没有为你工作.这是一个会.但首先,审查触发此错误的条件:
如果在垃圾收集中花费了太多时间,则并行收集器将抛出OutOfMemoryError:如果超过98%的总时间用于垃圾收集并且回收的堆少于2%
因此,您必须消耗几乎所有的堆,保持分配,然后分配大量垃圾.把很多东西放进Map去是不会为你做的.
public static void main(String[] argv)
throws Exception
{
List<Object> fixedData = consumeAvailableMemory();
while (true)
{
Object data = new byte[64 * 1024 - 1];
}
}
private static List<Object> consumeAvailableMemory()
throws Exception
{
LinkedList<Object> holder = new LinkedList<Object>();
while (true)
{
try
{
holder.add(new byte[128 * 1024]);
}
catch (OutOfMemoryError ex)
{
holder.removeLast();
return holder;
}
}
}
Run Code Online (Sandbox Code Playgroud)
该consumeAvailableMemory()方法用相对较小的内存块填充堆."相对较小"很重要,因为JVM会将"大"对象(我的经验中为512k字节)直接放入终身代,让年轻一代空着.
在我消耗了大部分堆之后,我只是分配并丢弃.这个阶段较小的块大小很重要:我知道我将有足够的内存用于至少一次分配,但可能不超过两次.这将使GC保持活动状态.
运行它会在一秒钟内产生所需的错误:
> java -Xms1024m -Xmx1024m GCOverheadTrigger
Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
at GCOverheadTrigger.main(GCOverheadTrigger.java:12)
Run Code Online (Sandbox Code Playgroud)
而且,为了完整性,这里是我正在使用的JVM:
> java -version
java version "1.6.0_45"
Java(TM) SE Runtime Environment (build 1.6.0_45-b06)
Java HotSpot(TM) 64-Bit Server VM (build 20.45-b01, mixed mode)
Run Code Online (Sandbox Code Playgroud)
现在我的问题是你:为什么你想在世界上做这个?