Философия Java


Как работает сборщик мусора - часть 4


Как упоминалось ранее, в описанной здесь JVM память резервируется большими блоками. Если вы резервируете большой объект, он получает свой собственный блок. Строгие правила остановки-и-копирования требуют копирования каждого живого объекта из исходной кучи в новую до того, как вы сможете освободить старую, что занимает много памяти. С блоками, СМ может обычно использовать мертвые блоки для копирования объектов, когда они будут собраны. Каждый блок имеет счет генерации, для слежения, жив ли он. В обычном случае создаются только блоки, так как СМ производит компактное расположение; все другие блоки получают увеличение своего счета генерации, указывающее, что на них есть ссылка откуда-либо. Это обработка обычного случая большинства временных объектов с коротким временем жизни. Периодически производится полная уборка — большие объекты все еще не копируются (просто получают увеличения счета генерации), а блоки, содержащие маленькие объекты, копируются и уплотняются. JVM следит за эффективностью СМ, и если она становится расточительной относительно времени, поскольку все объекты являются долгожителями, то она переключается на пометку-и-уборку. Аналогично, JVM следит, насколько успешна пометка-и-уборка, и, если куча становится слишком фрагментирована, вновь переключается на остановку-и-копирование. Это то, что составляет “адаптивную” часть, так что в завершении можно сказать труднопроизносимую фразу: “адаптивность генерирует остановку-и-копирование с пометкой-и-уборкой”.

Есть несколько дополнительный возможностей ускорения в JVM. Особенно важно включение операции загрузчика и Just-In-Time (JIT) компилятора. Когда класс должен быть загружен (обычно перед тем, как вы хотите создать объект этого класса), происходит поиск .class файла и байт-код для класса переносится в память. В этом месте один из подходов - упростит JIT весь код, но здесь есть два недостатка: это займет немного больше времени, что отразится на продолжительности работы программы, увеличив ее, и это увеличит размер выполнения (байт-код значительно компактнее, чем расширенный JIT-код), а это приведет к разбиению на страницы, которые значительно замедлят программу. Альтернативой является ленивое вычисление, что означает, что код не является JIT-компилированные, если это ненужно. Таким образом, код, который никогда не выполняется, никогда не будет компилироваться JIT.




Начало  Назад  Вперед



Книжный магазин