运行时数据区域

2018-12-14  本文已影响0人  平头哥2015

Java虚拟机通过内存动态分配和垃圾收集技术来帮助程序员管理内存。Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为几个不同的数据区域,包括程序计数器、堆、虚拟机栈、本地方法栈和方法区。这些区域都有各自的用途,以及创建和销毁的时间。

程序计数器

程序计数器是一块较小的内存空间。

作用

程序计数器是当前线程所执行的字节码的行号指示器。在虚拟机的概念模型中,字节码解释器工作时都是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。

特性


Java虚拟机栈

虚拟机栈描述的是Java方法执行的内存模型。

作用

每个方法被执行的时候都会创建一个栈帧(方法运行期的基本数据结构)用于存储局部变量表、操作栈、动态链接、方法出口等信息。每个方法被调用直至执行完成的过程都对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。
局部变量表存放了编译器可知的各种基本数据类型、对象引用(reference类型)和returnAddress类型。其中64位长度的long和double类型的数据会占用2个局部变量空间(Slot),其余的数据类型只占用1个。

特性

JVM参数


本地方法栈

作用

本地方法栈与虚拟机栈的作用非常相似,区别不过是虚拟机栈为虚拟机执行Java方法(即字节码)服务,而本地方法栈则是为虚拟机使用到的Native方法服务。

特性

JVM参数


Java堆

对于大多数应用来说,Java堆是Java虚拟机所管理的内存中最大的一块。

作用

Java堆唯一的目的就是存放对象实例,几乎所有的对象实例和数组都在这里分配内存。

特性

划分

JVM参数

异常分析

Java堆的异常分析首先通过内存映像分析工具(如Visual VM、Eclipse Memory Analyzer)对dump出来的堆转储快照进行分析,确认内存中的对象是否是必要的,也就是先确定是出现了内存泄漏,还是内存溢出。如果是内存泄漏,就进一步通过工具查看泄漏对象到GC Roots的引用链,确认垃圾收集器无法自动回收泄漏对象的原因;如果不存在泄漏,就只能尝试调大堆内存和从代码上缩短对象的生命周期。


方法区

方法区有个别名叫做Non-Heap(非堆)。因为HotSpot虚拟机的设计团队选择把GC分代收集扩展至方法区,所以很多人又称方法区为永久代。

作用

方法区用于存储已经被虚拟机加载的类信息(如类名、访问修饰符、字段描述、方法描述等)、常量、静态变量、即时编译器编译后的代码等数据。

特性

JVM参数

异常分析

方法区内存溢出常出现在以下的应用场景:


运行时常量池

运行时常量池是方法区的一部分

作用

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

特性


直接内存

直接内存并不是虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域,但是这部分内存也被频繁地使用。

作用

JDK 1.4新加入了NIO(New Input/Output)类,引入了一种基于通道(Channel)与缓冲区(Buffer)的I/O方式,它可以使用Native函数库直接分配堆外内存,然后通过一个存储在Java堆里面的DirectByteBuffer对象作为这块内存的引用进行操作。这样能在一些场景中避免在Java堆和Native堆中来回复制数据,显著提高性能。

特性

JVM参数

上一篇 下一篇

猜你喜欢

热点阅读