java虚拟机运行时内存分区

来源:互联网 发布:淘宝新店如何引流量 编辑:程序博客网 时间:2024/05/07 21:35
Java虚拟机在执行java程序的过程中会把它所管理的内存划分为若干个不同的数据区域,主要包括:方法区、虚拟机栈、本地方法栈、堆、程序计数器。其中,java堆和方法区是线程共享的数据区,其他几个都属于线程私有的。

程序计数器:

程序计数器是一块较小的内存空间,它的作用可以看做是当前线程所执行的字节码的行号指示器字节码解释器的工作就是通过改变这个计数器的值来选取下一条需要执行的字节码指令分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。

如果线程正在执行的是java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是Native方法,这个计数器的值为空(undefined)
此内存区域是唯一一个在Java虚拟机规范中没有规定任何OutofMemoryError情况的区域

Java虚拟机栈:

虚拟机栈描述的是Java方法执行的内存模型,每个方法被执行的时候都会创建一个线帧,用于存储局部变量表、操作栈、动态链接、方法出口等信息。每一个方法 被调用至执行完成的过程,就对应着一个线帧在虚拟机栈中从入栈到出栈的过程。

我们通常把Java内存区分为堆内存栈内存。栈内存指的就是现在所讲的虚拟机栈,或者说是虚拟机栈中局部变量表部分.局部变量表所需的内存空间在编译期间完成分配。在方法运行期间不会改变局部变量表的大小
在java虚拟机栈中,规定了两个异常,StackOverflowError和OutOfMemoryError异常

本地方法栈:

本地方法栈和虚拟机栈所发挥的作用非常相似,区别在于虚拟机栈为虚拟机执行java方法,而本地方法栈则为虚拟机执行native方法
有些虚拟机(如HotSpot)直接把本地方法栈和虚拟机栈合二为一

java堆:

java堆是java虚拟机所管理的内存中最大的一块。java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。在此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。
java堆是垃圾回收器管理的主要区域,因此很多时候被称为"GC堆"

Java堆可以处于物理上不连续的内存空间,只要逻辑上连续的即可。在实现上,既可以实现固定大小的,也可以是扩展的。
由于现在收集器基本上都是采用分代收集算法,所以java堆中可以细分为:新生代和老年代。在细致一点可以分为:Eden空间、 From Survivor空间、To Survivor空间等。
如果在堆中没有内存完成实例分配,并且堆也无法再扩展时,将会抛出OutOfMemoryError异常

方法区:

方法区与java堆类似,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据
当方法区无法满足内存分配需求时,将会抛出OutOfMemoryError异常

运行时常量池:

运行时常量是方法区的一部分。用于存放编译期生成的各种字面量和符号的引用,这部分内容将在类加载后进入方法区的运行时常量池中存放。除了保存class文件中描述的符号引用外,还会把翻译出来的直接引用也存储在运行时常量池。
运行常量池相对于class文件常量池的另一个重要特性是具备动态性,java语言并不是要求常量一定在编译期产生,也就是说并非预置入class文件的常量池的内容才能进入运行常量池,运行期间也可以将新的常量放入池中。例如String 的intern()方法
这部分会抛出OutOfMemoryError异常

个人见解:

程序计数器:存放当前线程所执行字节码的行号
本地方法栈:作用与虚拟机栈类似,区别在于执行的为native方法
java堆:存放对象实例
方法区:存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据
运行时候常量池:存放编译期生成的各种字面量和符号的引用翻译出来的直接引用
java虚拟机栈:描述Java方法执行的内存模型,存放存储局部变量表、操作栈、动态链接、方法出口等信息
局部变量表:存放编译期可知的各种基本数据类型(boolean、byte、char、short、int、float、long、double)、对象引用类型和returnAddress类型

深入理解java虚拟机(第二版)周志明 读书笔记
近期才开始写博客,有理解错误或者不完善的地方 可以发邮件给我,谢谢
wangli_it@163.com

1 0
原创粉丝点击