Java虚拟机所管理的内存的结构

本文详细介绍了Java虚拟机(JVM)的内存管理区域,包括程序计数器、虚拟机栈、本地方法栈、堆和方法区。每个区域都有其特定的功能和作用,如虚拟机栈用于Java方法执行的内存模型,而堆则是所有线程共享的最大内存区域。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

读深入理解JAVA虚拟机 第二章,记一下内容

Java虚拟机所管理的内存将会包括以下几个运行时数据区域:

方法区 Method Area; 虚拟机栈 VM Stack ; 本地方法栈 Native Method Stack
堆 Heap ; 程序计数器Program Counter Register

1,程序计数器Program Counter Register
一块较小的内存空间,非所有线程共享的区域,每个程序计数器,都会记录当前线程执行到的位置。
由于多线程之间会互相切换,为了在切换以后还能恢复到正确的执行位置,每条线程都有自己独立的程序计数器,他们之间互不影响,独立存储,称这块区域为“线程私有”的内存。
如果正在执行的是java方法,那么计数器记录的就是正在执行的虚拟机字节码指令的地址;如果正在执行的是Native方法,计数器就为空(Undefined).
虚拟机字节码,字节码解释器工作时,就是通过改变程序计数器的值来选取下一条需要执行的字节码指定,分支,循环,跳转,异常处理,线程恢复等基础功能都需要依赖这个计数器来完成。

2,虚拟机栈 VM Stack
线程私有的,生命周期与线程相同
虚拟机栈描述的是Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧(Stack Frame,方法运行时的基础数据结构),用于存储局部变量表,操作数栈,动态链接,方法出口等信息。
每个方法调用直至执行完成,都对应着一个栈帧在虚拟机栈中入栈到出栈的过程。
虚拟机栈中有一个局部变量表的部分,存放了编译期可知的八大基本数据类型对象引用类型(reference),returnAddress类型(指向一条字节码指令的地址)
局部变量表所需的空间会在编译期分配完成。当进入一个方法时,这个方法需要在栈帧中分配多大的局部变量空间是完全确定的,在运行期间是不会改变局部变量表大小的。

3,本地方法栈 Native Method Stack
本地方法栈为虚拟机使用到的native方法服务,和虚拟机栈类似,只是一个是java方法,一个是本地方法。虚拟机规范中没有对本地方法使用的语言,方式,数据结构做出强制规定,可以由具体的虚拟机自由实现。甚至有的虚拟机把本地方法栈和虚拟机栈合二为一。

4,堆 Heap
虚拟机所管理的内存中最大的一块,被所有线程共享的一块区域,在虚拟机启动时创建。用来存放对象实例。虚拟机规范中说:所有的对象实例以及数组都要在堆上分配(随着技术的发展,可能有一些其他的优化方案,就不那么绝对了)

垃圾收集:
Java堆是垃圾收集器管理的主要区域,因此很多时候也被称做GC堆,Garbage Collected Heap.
因为收集器都采用分代算法,所有java堆可以细分为:新生代,老年代,,多个线程私有的分配缓冲区(Thread Local Allocation Buffer,TLAB)等,都是存放的对象实例。
划分目的是为了更好的回收/分配内存。

5,方法区 Method Area
所有线程共享区域,用于存储已经被虚拟机加载的常量,静态变量,类信息,即时编译器编译后的代码等数据。
虚拟机规范把方法区描述为堆中的一个逻辑部分,但是它的别名叫做Non-Heap(非堆),目的就是为了和Java堆区分开来。
虚拟机规范可以允许方法区不实现垃圾回收,内存在这个区域的回收主要是常理池的回收和对类型的卸载。所以这个部分的回收其实是必要的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值