Ответ 1
Поскольку вы не приняли никакого ответа, я предполагаю, что никто из них не работал на вас. Вот один из них. Но сначала рассмотрим условия, которые вызывают эту ошибку:
Параллельный коллектор выкинет 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;
}
}
}
Метод consumeAvailableMemory()
заполняет кучу относительно небольшими фрагментами памяти. "Относительно мало" важно, потому что JVM будет помещать "большие" объекты (512 k байт в моем опыте) непосредственно в поколение поколений, оставив молодое поколение пустым.
После того, как я использовал большую часть кучи, я просто выделяю и отбрасываю. Меньший размер блока на этом этапе важен: я знаю, что у меня будет достаточно памяти для хотя бы одного распределения, но, вероятно, не более двух. Это будет держать 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)
И теперь мой вопрос для вас: почему в мире вы хотели бы это сделать?