既然你没有接受任何答案,我就假设它们都不适合你。这是一个会的。但首先,回顾一下触发此错误的条件:
如果在垃圾回收中花费了太多时间,并行收集器将抛出一个 OutOfMemor 错误:如果超过 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;
}
}
}
该方法用相对较小的内存块填充堆。“相对较小”很重要,因为JVM会将“大”对象(根据我的经验为512k字节)直接放入终身一代,使年轻一代空着。consumeAvailableMemory()
在我消耗了大部分堆之后,我只是分配和丢弃。此阶段中较小的块大小很重要:我知道我将有足够的内存用于至少一个分配,但可能不超过两个。这将使 GC 保持活动状态。
运行此命令会在一秒钟内产生所需的错误:
> java -Xms1024m -Xmx1024m GCOverheadTrigger
Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
at GCOverheadTrigger.main(GCOverheadTrigger.java:12)
而且,为了完整起见,以下是我正在使用的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)
现在我问你:你为什么要这样做?