JVM自动内存管理-运行时数据区域

引言

Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的“高墙”,墙外面的人想进去,墙里面的人想出来。
搞C和C++的程序猿,拥有对象的“所有权”,担负着每一个对象生命开始到终结的维护责任,也就是用完得自己释放对象;
对于Java程序猿来说,管杀不管埋,对象用完就不管了,也不容易出现内存泄漏和内存溢出问题,这是JVM在帮我们擦屁股呢,但是一旦出现问题,如果不清楚JVM是如何使用内存的,那排查问题就要爆炸了。

所以这篇文章介绍JVM运行时数据区

运行时数据区

JVM管理的内存包括以下几个运行时数据区域,看图
运行时数据区
Java虚拟机是一个假想的计算机,就理解成计算机的内存结构好了,下面介绍每块都是干啥用的。

程序计数器

.java文件经过编译成.class文件,然后加载成字节码执行。在多线程情况下,线程A执行到某一行的时候,线程B得到CPU时间片,然后执行到某一行,当线程A再次得到CPU时间片执行的时候,会从上次执行到那一行继续往下执行。这里就要靠程序计数器来确定执行上次执行到哪里了,才能接着往下执行,所以可以确定程序计数器是线程私有的,它占的内存空间较小,各个线程之间程序计数器互不影响,独立存储。程序计数器可以理解成是当前线程所执行的字节码的行号指示器。

Java虚拟机栈

提到栈这种数据结构,大家应该很熟悉,先进后出。Java虚拟机栈也是这么一种数据结构,它也是线程私有的,描述的是Java方法执行的内存模型:每个方法在执行的同时会创建一个栈帧,用于存储局部变量表,操作数栈,动态链接,方法出口等信息。方法从调用到执行完成的过程,对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。
栈帧用于存储局部变量表,操作数栈,动态链接,方法出口信息,好像还挺复杂的。现在先简单理解成栈帧中存放的是方法执行是需要的所有数据,确保Java方法能顺利执行完。

本地方法栈

与虚拟机栈非常相似,也是线程私有的,他俩的区别就是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则为悉尼及使用到的Native方法服务。

Java堆

堆(Heap)是Java虚拟机所管理的内存中最大的一块,是所有线程共享的一块区域,在虚拟机启动时候创建,几乎所有的对象实例都在这里分配内存。(还要考虑栈上分配,标量替换等情况)
当然,堆也是Java垃圾收集器管理的主要区域。按内存回收角度,由于现在的收集器基本都使用分代收集算法,可以把堆分成新生代和老年代;再细一点,新生代分为Eden区,From Survivor区和To Survivor区(HotSpot默认他们的大小比例是8:1:1)见下图,当然这些比例可以通过虚拟机参数控制。
堆

内存分配的角度线程共享的堆中可能划分出多个线程私有的分配缓冲区(简称TLAB,在线程初始化时,同时也会申请一块指定大小的内存,只给当前线程使用,这样每个线程都单独拥有一个空间,如果需要分配内存,就在自己的空间上分配,这样就不存在竞争的情况,可以大大提升分配效率),不过无论如何划分,都与存放内容无关,无论哪个区域,保存的仍然是对象实例,作用都是为了能更好更快地分配和回收内存。

方法区

方法区也是各个线程共享的内存区域,它存储的是已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据
Emmmm,常量和静态变量好理解,已被虚拟机加载的类信息是啥?即时编译器编译后的代码又是啥?不要方,一个个来。.class文件被类加载器加载成字节码文件然后交由JVM执行,加载过程中产生的信息(比如类型信息,字段信息,方法信息等等)就是被虚拟机加载的类信息,存放到方法区;
JVM有一个优化叫做JIT,也就是即使编译优化,我们知道Java是解释型语言,速度肯定是不如C这种编译型的,那么很明显的一个可行的优化就是把部分热点字节码也直接编译成可执行的机器码(也就是你所说的即时编译器编译后的代码),这样速度就和编译型的一样了。

运行时常量池
是方法区的一部分,.class文件中除了有类的版本,字段,方法,接口等描述信息外,还有一个是常量池,用于存储编译器生成的各种字面量和符号引用,这部分内容在类加载后进入方法区的运行时常量池中存放。
Java语言并不要求常量一直只有编译期才能产生,也就是说并非预先在Class文件中的常量池内容才能进去方法区的运行时常量池,运行期间也可能将新的常量放入常量池中,比如String类的intern()方法。

JVM运行时数据区介绍到这里就结束了,主要是虚拟机栈,堆,方法区这三块,每部分分别存储什么数据以及特点。下篇如何创建一个Java对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值