Мы заметили это в серверном продукте. При изготовлении большого количества крошечных предметов, которые быстро выбрасываются, сборщик мусора не может успевать. Проблема становится более заметной, когда крошечные объекты имеют указатели на более крупные объекты (например, объект, который указывает на большой char[]
). GC, похоже, не понимает, что если он освобождает крошечный объект, он может освободить более крупный объект. Даже при непосредственном вызове System.gc()
это все еще было огромной проблемой (как для 1,5, так и для 1,6 виртуальных машин)!
Что мы в итоге сделали и что я рекомендую вам, так это поддерживать пул объектов. Когда ваш объект больше не нужен, бросьте его в бассейн. Когда вам нужен новый объект, возьмите его из пула или выделите новый, если пул пуст. Это также сэкономит небольшое количество времени по сравнению с чистым распределением, поскольку Java не нужно очищать (bzero
) объект.
Если вас беспокоит слишком большой размер пула (и, как следствие, потеря памяти), вы можете либо удалить произвольное количество объектов из пула на регулярной основе, либо использовать слабые ссылки (например, используя java.util.WeakHashMap
) ). Одним из преимуществ использования пула является то, что вы можете отслеживать частоту распределения и итоги, а также настраивать их соответствующим образом.
Мы используем пулы char[]
и byte[]
, и мы поддерживаем отдельные «корзины» размеров в пуле (например, мы всегда выделяем массивы размеров, которые имеют степени двух). Наш продукт много строит, и использование пулов показало значительное улучшение производительности.
Примечание: в общем, GC отлично справляется со своей работой. Мы только что заметили, что с небольшими объектами, которые указывают на большие структуры, GC, кажется, не очищает объекты достаточно быстро, особенно когда виртуальная машина находится под нагрузкой процессора. Кроме того, System.gc()
- это просто подсказка, которая поможет запланировать поток финализатора для выполнения дополнительной работы. Слишком частый вызов приводит к значительному снижению производительности.