大数跨境
0
0

JVM基础知识之内存区域

JVM基础知识之内存区域 二进制跳动
2021-04-02
2
导读:JVM基础知识之内存区域


1.堆

如 JVM 内存区域划分图所示,JVM 中占用内存最大的区域,就是堆(Heap),我们平常编码创建的对象,大多数是在这上面分配的,也是垃圾回收器回收的主要目标区域。


2.Java 虚拟机栈

JVM 的解释过程是基于栈的,程序的执行过程也就是入栈出栈的过程,这也是 Java 虚拟机栈这个名称的由来。


Java 虚拟机栈是和线程相关的。当你启动一个新的线程,Java 就会为它分配一个虚拟机栈,之后所有这个线程的运行,都会在栈里进行。

Java 虚拟机栈,从方法入栈到具体的字节码执行,其实是一个双层的栈结构,也就是栈里面还包含栈。


3.程序计数器

既然是线程,就要接受操作系统的调度,但总有时候,某些线程是获取不到 CPU 时间片的,那么当这个线程恢复执行的时候,它是如何确保找到切换之前执行的位置呢?这就是程序计数器的功能。

和 Java 虚拟机栈一样,它也是线程私有的。程序计数器只需要记录一个执行位置就可以,所以不需要太大的空间。事实上,程序计数器是 JVM 规范中唯一没有规定 OutOfMemoryError 情况的区域。


4.本地方法栈

与 Java 虚拟机栈类似,本地方法栈,是针对 native 方法的。我们常用的 HotSpot,将 Java 虚拟机栈和本地方法栈合二为一,其实就是一个本地方法栈,大家注意规范里的这些差别就可以了。


5.元空间

元空间是一个容易引起混淆的区域,原因就在于它经历了多次迭代才成为现在的模样。关于这部分区域,我们来讲解两个面试题,大家就明白了。


元空间是在堆上吗?

答案:元空间并不是在堆上分配的,而是在堆外空间进行分配的,它的大小默认没有上限,我们常说的方法区,就在元空间中。

字符串常量池在那个区域中?

答案:这个要看 JDK 版本。


在 JDK 1.8 之前,是没有元空间这个概念的,当时的方法区是放在一个叫作永久代的空间中。

而在 JDK 1.7 之前,字符串常量池也放在这个叫作永久带的空间中。但在 JDK 1.7 版本,已经将字符串常量池从永久带移动到了堆上。

所以,从 1.7 版本开始,字符串常量池就一直存在于堆上。


6.直接内存

直接内存,指的是使用了 Java 的直接内存 API,进行操作的内存。这部分内存可以受到 JVM 的管控,比如 ByteBuffer 类所申请的内存,就可以使用具体的参数进行控制。

需要注意的是直接内存和本地内存不是一个概念。

直接内存比较专一,有具体的 API(这里指的是ByteBuffer),也可以使用 -XX:MaxDirectMemorySize 参数控制它的大小;

本地内存是一个统称,比如使用 native 函数操作的内存就是本地内存,本地内存的使用 JVM 是限制不住的,使用的时候一定要小心。

【声明】内容源于网络
0
0
二进制跳动
15 年 + 技术老兵 架构师|技术总监|科技创业技术合伙人 曾任职苏宁科技、电讯盈科、联想云 专注架构设计与技术落地
内容 739
粉丝 0
二进制跳动 15 年 + 技术老兵 架构师|技术总监|科技创业技术合伙人 曾任职苏宁科技、电讯盈科、联想云 专注架构设计与技术落地
总阅读78
粉丝0
内容739