JVM运行时内存区域

本文最后更新于:2022年7月20日 下午

概览:JVM内存结构

预警!仅用于本人快速自学,不过欢迎指正。

JVM内存结构概览

1.程序计数器

作用:记住下一条jvm指令的执行地址。

java方法,记录虚拟机字节码指令地址,本地方法,值应当为空

线程私有的,不会存在内存溢出问题

2.虚拟机栈

每个线程运行时需要的内存,称为虚拟机栈

java方法执行的线程内存模型

每个栈由多个栈帧组成,对应着每个方法调用时所占用的内存。

包含局部变量表: –> 存放了编译期间可知的Java基本数据类型和对象引用(一个指向对象的指针)。

垃圾回收不涉及栈内存:方法调用完成之后就会释放。

3.本地方法栈

native方法

给本地方法运行提供内存空间

4.堆

通过new关键字创建的对象,都会使用堆内存。

堆是线程共享的,堆中的对象需要考虑线程安全问题。

此外,堆中可以划分出多个线程私有的分配缓冲区:TLAB,这个可以提升对象分配的效率

堆是有垃圾回收机制的。

class对象、static静态变量都是放在堆中的。

堆大小可扩展:

1
2
-Xmx 
-Xms

5.方法区

存储已经被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据

jvm启动时被创建

JDK1.6的时候,方法区存放于永久代(堆中),运行时常量池还有String Table也放在永久代中。

JDK1.8中,方法区由元空间实现,存放于本地内存中,运行时常量池也在元空间之中。而StringTable在堆中

5.1运行时常量池

这是方法区的一部分

常量池是一张常量表,虚拟机指令根据这个找到要执行的类名、方法名、参数类型、字面量。eg: 方法名字System.out.println()

运行时常量池是 .class文件中的,当类被加载的时候,常量池信息就会放在运行时常量池,并把里面的符号地址变为真实地址。

具备动态性:运行期间也可以将新的常量放入池中,eg:String的intern方法。

6.直接内存

常用于NIO操作,用于数据缓冲区

分配回收成本比较高,但是读写性能高

不受jvm内存回收管理


其他

Java虚拟机的多线程是通过线程轮流切换、分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器(对多核处理器来说是一个内核)都只会执行一条线程中的指令。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!