Quest JVM: область памяти Java

Эта серия заметок в основном базируется на «глубоком понимании виртуальной машины Java: JVM расширенные возможности и лучшие практики 2-е издание», эта книга отмечает исследование.

очертание

Виртуальная машина Java для программистов, чтобы разделить много работы управления памятью, а не утечки памяти и проблемы переполнения памяти, как склонные, как C / C ++, и именно это, если есть проблемы, приводящие к утечкам памяти и переполнение областям там, будут трудно расследование. Так что хороший Java программист должен иметь достаточные знания о виртуальной машине Java, JVM является обязательным курсом для вас.

область данных выполнения

В соответствии с «Спецификация виртуальной машины Java (Java SE версии 7),» разделить область памяти под управлением JVM следующим образом :



каждая область памяти имеет свои собственные использования, а также создание и уничтожение времени, запустит виртуальную машину с некоторыми областями и есть некоторая область полагаться на пользовательских потоков , созданных и уничтоженных, а затем описание этих областей памяти.

счетчик программ

Счетчик программы (Program Counter Register) представляет собой частный поток область памяти, номер строки байткодом указатель в настоящее время выполнения резьбы, небольшой объем памяти.

Когда байт-код интерпретатора (исходный код Java компилируется в байт-код, интерпретируемого в исполнение во время выполнения работы машины), то путем изменения значения счетчика команд, чтобы выбрать следующий байт-код будет выполняться. Отделение, петля, счетчик программа переходит все зависит выполняется.

Когда поток выполнения метода Java, счетчик программы записывает адрес инструкции виртуальной машины байткода запущенного; Native метод, когда поток выполнения, значение счетчика программы является нулевым (Undefined). Счетчик программы является единственным не в указанной области памяти OutOfMemoryError Java Virtual Machine Specification.

Java Virtual Machine стек

Стек Java Virtual Machine (Java Stack) является поточно-частная область памяти, ее жизненный цикл и тот же поток. Является ли виртуальный стек машины модели памяти Java описанный способ выполняется: Каждый метод создает выполнение в стеке кадров (кадр стека) , чтобы сохранить локальную переменную таблицы информацию, операндами стека, динамическое связывание, экспорта метод. Каждый метод вызов от начала до завершения исполнения кадра стека соответствует виртуальной машине из стека в стек стеке процесса.

Таблица локальных переменных хранятся компиляции различных известных базовых типов данных (булево байт символ короткий INT длинный двойной поплавок), ссылки на объект и тип returnAddress (адрес, указывающий на инструкции байт-код). Требуется локальная таблица переменная, созданная во время компиляции пространства памяти, выделенной, при входе в метод требует много места для локальных переменных, выделенных в кадре стека полностью определен, метод не изменяется во время работы локальной переменной размера таблицы.

В спецификации виртуальной машины Java, Java Virtual Machine стек может быть две аномалии: StackOverflowError и OutOfMemoryError. Если глубина в потоке запроса стек больше глубин виртуального стека машина StackOverflowError. Не правомочными, если достаточно стек памяти динамически расширяемый виртуальную машину, она будет OutOfMemoryError.

Родные стеки метод

Native метод стека (метод Native Stack) с эффектом стека виртуальной машины Java, является потоком частного , разница в том , что виртуальный стеке машины Java для выполнения службы метода Java, нативный метод стеки к услугам нативного метода, виртуальная спецификации машины не нативный метода стек обязательным в виртуальной машине HotSpot на виртуальную машину нативный метод штабеля и укладывает вместе взятых. Эта область памяти может также бросить StackOverflowError и OutOfMemoryError.

Java кучи

Java кучи (Java Heap) все часть общих нитей из области памяти, но и виртуальная машина Java управляется самой большой блок памяти создается при запуске виртуальной машины. Единственная цель этой области памяти хранится экземпляр объекта , почти все экземпляры объектов здесь , чтобы выделить память.

Java сборщик мусора управления кучи кучи является основной областью, также известный как «GC кучу.» Теперь сборщик мусор в основном с использованием поколениями алгоритма сбора, поэтому с точки зрения восстановления памяти, Java куча также может быть разбит на: старое и новое поколения, новое поколение пространства можно разделить на Эдем Из Survivor пространства, чтобы Survivor пространство ,

Как показано ниже:

С точки зрения распределения памяти, потоки разделяют кучи Java могут быть разделены на несколько потоков частных выделить буфер (Thread Local Allocation буфер, TLAB). Виртуальная машина для выделения памяти для нового объекта, куча ранее выделенная для каждого потока небольшой памяти в Java, называется локальной нитка буфер распределения (TLAB). Какой поток для выделения памяти, когда она выделяется на TLAB, какой поток, только TLAB выбежать и назначить новое TLAB, будет синхронизироваться замок (для безопасности потоков в параллельных случае).

стек Java может быть в прерывистом физическом пространстве памяти, до тех пор, как может быть логически смежными. Если не хватает памяти для завершения кучи выделено экземпляров, и не может быть продлен, когда бросит OutOfMemoryError.

Методы района

Метод района (метод Aera) и куча Java, так же , как поток разделяют область памяти для хранения виртуальной машины была загружена информацию о классе, константы, статические переменные, время компилятор для компиляции кода и других данных. Виртуальная машина спецификация, она описана как логическая часть стека, но он должен быть фактически отличается от Java кучи.

从分代收集的角度看,方法区也被称做永久代(Permanent Generation),实际上两者并不等价,只是因为 HotSpot 虚拟机使用永久代实现了方法区,对于其他虚拟机(JRockit、IBM J9)是不存在永久代概念的。

使用永久代实现方法区,更容易出现内存溢出问题(永久代有 -XX:MaxPermSize 的上限),所以在 JDK1.8 中,HotSpot 就取消了永久代(JEP122),取而代之的是元空间(MetaSpace),元空间是方法区新的实现,而且使用的是本地内存不是虚拟机内存。原先永久代中类的元信息会放入元空间,类的静态变量和常量会放入 Java 堆。

永久代也并不是指真的“永久”存在,只是说这部分内存回收(常量池回收和对类型的卸载)的成绩难以令人满意,条件也非常苛刻。

方法区会有 OutOfMemoryError 异常。

运行时常量池

运行时常量池(Runtime Constant Pool)是方法区的一部分。Class文件中除了有类的版本信息、字段、方法、接口等描述信息外,还有一项信息就是常量池,用于存放编译期间生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池中,另外翻译出来的直接引用也会存储在这个区域中。

这个区域另外一个特点就是动态性,Java并不要求常量就一定要在编译期间才能产生,运行期间也可以在这个区域放入新的内容,String.intern()方法就是这个特性的应用。此区域有 OutOfMemoryError 异常。

JDK1.6及之前,常量池是位于方法区中的,但在JDK1.7的时候常量池挪到了堆内存,也就是常量池和对象共享 Java 堆,所以在 Java7 以后,常量池就不在方法区分配了,而是在 Java 堆 中分配。

直接内存

直接内存(Direct Memory)并不是虚拟机运行时数据区的一部分,也不是 Java 虚拟机规范中定义的内存区域。但这部分区域被频繁的使用,也可能导致 OutOfMemory 异常出现。

JDK1.4 中加入了 NIO,这是一种基于通道(Channel)和缓冲区的 I/O 方式,它可以使用 Native 函数库直接分配堆外内存,然后通过一个存储在 Java 堆中的 DirectByteBuffer 对象作为这块内存的引用进行操作。这样显著提高了性能,因为避免了在 Java 堆和 Native 堆中来回复制数据。显然,本机直接内存的分配不会受到 Java 堆大小的限制,但是,既然是内存,肯定还是会受到本机总内存(包括RAM、SWAP区)大小以及处理器寻址空间的限制。在配置虚拟机参数时,会根据实际内存配置 -Xmx 等,但经常忽略直接内存,使得各个内存区域总和大于了物理内存,从而导致动态扩展时出现 OutOfMemoryError。

рекомендация

отwww.cnblogs.com/cellei/p/12113354.html
рекомендация