Quest JVM: Java memory area

This series of notes is mainly based on "in-depth understanding of the Java Virtual Machine: JVM advanced features and best practices 2nd Edition", this book study notes.

Outline

Java Virtual Machine for programmers to share a lot of memory management work, not memory leaks and memory overflow problems as prone as C / C ++, and it is this, if there are problems leading to memory leaks and overflow areas there, it will be difficult investigation. So a good Java programmer should have sufficient knowledge of the Java Virtual Machine, JVM is a required course for you.

Runtime data area

According to "Java Virtual Machine Specification (Java SE version 7)," divided memory area managed by the JVM as follows:



each memory area has its own uses, as well as the creation and destruction of time, will start the virtual machine with some areas and there is some area rely on user threads created and destroyed, followed by a description of these memory areas.

Program Counter

Program counter (Program Counter Register) is a thread private memory area, the line number bytecode pointer currently executing thread, is a small memory space.

When the bytecode interpreter (java source code is compiled into byte code, interpreted into machine runtime execution) work, it is by changing the value of the program counter, to select the next byte code to be executed. Branch, loop, the program counter jumps all depend executed.

When a thread executing Java method, a program counter records the address of the virtual machine bytecode instruction being executed; Native method when a thread of execution, a program counter value is null (Undefined). The program counter is the only one not in the specified area of ​​memory OutOfMemoryError Java Virtual Machine Specification.

Java Virtual Machine stack

Stack Java Virtual Machine (Java Stack) is thread-private memory area, its life cycle and the same thread. Is a virtual machine stack Java memory model described method performed: Each method creates an execution in the stack frame (Stack Frame) to store local variable table information, operand stack, dynamic linking, method exports. Each method call from start to completion of execution of a stack frame corresponds to a virtual machine from the stack to the stack of a process stack.

The local variable table stored compile various known basic data types (boolean byte char short int long double float), object references, and returnAddress type (address pointing to a byte code instruction). Required local variable table created during compilation memory space allocated, when entering a method requires much space for local variables allocated in the stack frame is fully defined, the method does not change during operation of the local variable table size.

In the Java Virtual Machine Specification, Java Virtual Machine stack there may be two anomalies: StackOverflowError and OutOfMemoryError. If the request thread stack depth is greater than the depth of the virtual machine stack will StackOverflowError. Not eligible if enough memory stack dynamically expanding virtual machine, it will OutOfMemoryError.

Native method stacks

Native method stacks (Native Method Stack) with the Java virtual machine stack effect, is thread private , the difference is that the Java virtual machine stack to perform Java method service, native method stacks to Native method services, virtual machine specification does not the native method stack made mandatory in the HotSpot virtual machine to virtual machine native method stacks and stacks the combined. This memory area can also throw StackOverflowError and OutOfMemoryError.

Java heap

Java heap (Java Heap) are all a piece of shared threads of memory region, but also the Java virtual machine managed by the largest block of memory is created when the virtual machine starts. The sole purpose of this memory area is stored object instance , almost all object instances are here to allocate memory.

Java garbage collector heap management heap is the main area, also known as "GC heap." Now garbage collector basically using generational collection algorithm, so from the perspective of memory recovery, Java heap can also be broken down into: the old and the new generation's; the new generation of space can be subdivided into Eden, From Survivor space, To Survivor space .

As shown below:

From the perspective of memory allocation, threads share the Java heap may be divided into multiple threads private allocate a buffer (Thread Local Allocation Buffer, TLAB). Virtual machine to allocate memory for the new object, the heap previously allocated for each thread a small memory in the Java, called local thread allocation buffer (TLAB). Which thread to allocate memory when it allocated on TLAB which thread, only TLAB run out and assign a new TLAB, will sync lock (for thread safety in the concurrent case).

Java stack may be in a discontinuous physical memory space, as long as can be logically contiguous. If there is not enough memory to complete the heap allocated instances, and can not be extended when will throw OutOfMemoryError.

Methods district

District method (Method Aera) and the Java heap, just as the thread shared memory area for storing virtual machine has been loaded class information, constants, static variables, the time compiler to compile the code and other data. Virtual machine specification, it is described as a logical part of the stack, but it should actually be distinguished from Java heap.

从分代收集的角度看,方法区也被称做永久代(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。

Guess you like

Origin www.cnblogs.com/cellei/p/12113354.html