| Главная » Статьи » 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 | |
| Просмотров: 351 | | |
| Всего комментариев: 0 | |