JVM运行时内存区域
本文最后更新于:2022年7月20日 下午
概览:JVM内存结构
预警!仅用于本人快速自学,不过欢迎指正。
JVM内存结构概览
1.程序计数器
作用:记住下一条jvm指令的执行地址。
java方法,记录虚拟机字节码指令地址,本地方法,值应当为空
线程私有的,不会存在内存溢出问题
2.虚拟机栈
每个线程运行时需要的内存,称为虚拟机栈
java方法执行的线程内存模型
每个栈由多个栈帧组成,对应着每个方法调用时所占用的内存。
包含局部变量表: –> 存放了编译期间可知的Java基本数据类型和对象引用(一个指向对象的指针)。
垃圾回收不涉及栈内存:方法调用完成之后就会释放。
3.本地方法栈
native方法
给本地方法运行提供内存空间
4.堆
通过new关键字创建的对象,都会使用堆内存。
堆是线程共享的,堆中的对象需要考虑线程安全问题。
此外,堆中可以划分出多个线程私有的分配缓冲区:TLAB,这个可以提升对象分配的效率
堆是有垃圾回收机制的。
class对象、static静态变量都是放在堆中的。
堆大小可扩展:
1 |
|
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 协议 ,转载请注明出处!