Главная » Статьи » Java » Java Ranger Basic

День 4/21
Memory in Java


В C++ тип данных адрес может быть преобразован к примитивному типу (к int или long). Имея код:

Node ref = new Node(...);

в C++ возможно следующее:

int adr = (int) ref;

и мы получим непосредственно адрес в памяти, то есть номер ячейки в памяти. Далее можно прибавить к adr + 4 и получить адрес следующей ячейки памяти.
Фактически в C++ можно преобразовывать адреса к целым типам, оперировать с ними как с целыми типами (складывать, умножать, делить и т.д.), а потом преобразовывать обратно в адреса. В C++ можно напрямую память компьютера в 8 ГБ рассматривать, как массив из 8 миллиардов байт.
C++, как и C – это языки для системного программирования. Это означает, что так или иначе у нас есть доступ ко всем потрохам компьютера (доступ к сырой памяти и т.д.). Это приводит к тому, что в ряде случаев на C++ можно написать программу, которая серьезно опережает Джаву по скорости, но только специфичные классы программ: математические расчеты, компьютерные игры. Но, с другой стороны, если случайно поменять память по ошибочному адресу, то это может привести к непредвиденным результатам.
В C++ есть адресная арифметика, это значит, что всегда можно преобразовать адрес в число целого типа, произвести над ним операции и преобразовать назад в адрес. Из-за этого объекты в памяти нельзя перемещать, адрес объекта должен сохраняться.
Когда речь идет о ссылках в Java, то тут нету адресной арифметики, как в адресах в C++. В Java ссылочный тип никак нельзя преобразовать к примитивному типу в принципе. Из-за этого объекты в памяти можно перемещать, главное, чтобы, идя по ссылке, мы попадали в те же самые данные.
Из-за этого в C++ существует фрагментация памяти. И может возникнуть такая ситуация, что у программы в heap есть еще 100 Мб свободной памяти, мы просим 1 Мб, а нам говорят, что памяти нету. Скорее всего, что это 100 Мб в сумме из многих маленьких кусочков. При этом менеджер памяти C++ должен помнить размеры и позиции всех этих кусочков памяти.
В Java в ситуации, когда обнаруживается, что есть несколько свободных кусков памяти, уборщик мусора замораживает эти программы (это говоря по-простому, а на самом деле GC – очень сложный процесс и он старается ничего не замораживать), после чего дефрагментирует память – копирует все занятые ячейки памяти, чтобы они шли подряд, а во всех ссылках переписывает адреса на новый участок памяти. После чего менеджеру памяти сообщает о новой границе и объеме свободной памяти. Такой тип называется копирующий сборщик мусора. То есть он имеет право перемещать объекты по памяти. Это приводит в тому, что в Java оператор new работает очень быстро, а из-за garbage collector виртуальная машина может тупить.
Если виртуальная машина обнаруживает, что память закончилась в Heap, она бросает OutOfMemoryError, если закончилась в Stack – StackOverflowError, если в PermGen – OutOfMemoryError. Еще нужно сказать, что исключение OutOfMemoryError – асинхронное, то есть оно может вылететь не в ответ на наши действия.

На рынке сейчас несколько виртуальных машин, основная сейчас HotSpot от Oracle, которая установлена у большинства. Она установлена на настольных ПК, для нее есть src, она бесплатная, она написана на C++, C и Assembler. Еще одна – это Dalvik для Android. Они обе соответствуют спецификации, обе работают, как описано в pdf’e, но поскольку делали их разные компании, работать они могут слегка по-разному. Также виртуальных машин существует большое количество версий.



В следующей теме мы рассмотрим: Loops

Источник: http://becomejavasenior.com/courses/?utm_source=Java+Email+Courses&utm_campaign=aa710df388-JavaRangerBasicIntro&utm_medi
Категория: Java Ranger Basic | (06.10.2015) W
Просмотров: 351 | Теги: Basic, ranger, java | Рейтинг: 0.0/0
Всего комментариев: 0
avatar