JVM的运行时内存结构

jvm的运行时内存结构

jvm的内存结构划分为多个不同的内存区,每个内存区都有各自的用途,都负责处理各自的数据类型.有些内存区的生命周期与jvm一致,有些与线程一致.不同的内存区在存储的数据类型和生命周期有区别,但是他们有共同的本质,就是存储程序的运行时数据.

这里写图片描述
jvm的内存区可以根据受访权限定义为线程共享和线程私有.

线程共享内存区

堆区

有些人非常粗粒度的将jvm中的内存区理解为仅有heap和stack,这样非常不全面.
堆在jvm启动的时候被创建,在实际的内存空间中是可以不连续的.

java堆是一块用来存储对象实例的内存区,用来存储对象实例,也是gc的重点区域.由此,jvm的设计者考虑是否一定需要将对象实例存储到堆区. TaoBaoVM实现off-heap,将生命周期较长的Java对象从heap转移到heap之外.还有一些技术,使得java堆区不再是Java对象内存分配的唯一选择.

存储在Java堆中的对象,生命周期长短各不相同,有的长有的短.有的是较短的瞬时对象,有的是极端情况下与jvm生命周期一致的对象,要采取不同的垃圾回收策略.分代收集由此而生.

堆的大小在jvm启动的时候就已经设置好了,可以通过选项”-Xms”表示堆区的起始内存,选项”-Xmx”表示堆区最大内存.一旦堆区超过”-Xmx”指定的最大内存,将会抛出OutOfMemory异常.

方法区

方法区也是允许所有的线程共享访问.方法区存储了每个java 类的结构信息,比如运行时常量池,字段,构造方法普通方法的字节码内容以及类,实例,接口初始化需要用到的特殊方法等数据.
在hotspot中,方法区仅仅只是逻辑上的独立,实际上还是包含在java堆区内.
方法区在jvm启动的时候被创建,实际内存空间也是可以不连续的.有些开发者愿意称之为”永久代”,主要是,方法区除了通过”-XX:MaxPermSize”设置内存大小进行动态扩展外,不会像堆区那样频繁gc,甚至可以显式指定是否需要回收.

方法区的内存大小通过”-XX:Max-PermSize”设置.超出则OOM异常.

运行时常量池

属于方法区的一部分,运行时常量池包含多种不同常量,类似于传统编程语言中的符号表,数据很丰富.

当类装载器成功将一个类或接口装载进JVM后,就会创建相对应的运行时常量池.由于运行时常量池所分配的内存来源于方法区,一旦所需要的内存大于方法区所能提供的最大值,运行时常量池也会OOM.

线程私有内存区

线程私有内存区是只允许被所属的独立线程进行访问的一类内存区,包括PC计数器,Java栈和本地方法栈3个内存区.

PC计数器

PC计数器是堆物理PC寄存器的一种抽象模拟,线程私有,生命周期与线程保持一致.当前线程正在执行Java方法,PC寄存器就会存储正在执行党的字节码指令地址.
为什么线程私有?这要说起PC计数器存在的意义.我们知道多线程在某个特定的时间段只会执行其中某一个线程的方法,CPU会不停地做任务切换.为了准确记录各个线程正在执行的当前字节码指令地址,最好的方法就是每个线程都来一个PC寄存器,达到县城之间独立计算的效果.**为什么要存储字节码指令地址?**JVM的字节码解释器需要通过改变PC寄存器的值来明确下一条应该执行什么样的字节码指令.

Java栈

Java栈也可以被称为Java 虚拟机栈.也是线程私有的,生命周期与线程的生命周期保持一致.
Java栈用于存储栈帧(Stack Frame),而栈帧存储的就是局部变量表,操作数栈,以及方法出口等.

相对于Java堆存储的是对象实例,Java栈中的局部变量表就是用于存储各种原始数据类型,对象引用以及returnAddress类型–即Java虚拟机内部的原始数据类型,用于表示一条字节码指令的操作码(opCode),
Java栈允许被实现成固定大小的内存或者是可动态扩展的内存大小.

本地方法栈

用于支持本地方法.(native方法)的执行.与Java栈类似.可以不实现.

自动内存管理

手动管理内存,以C/C++为代表,容易出现两大意外:内存溢出内存泄露.
内存泄露常见的场景:当你打算释放一个链表所引用的所有的空间时,却错误的只释放了链表的第一个元素,而剩下的元素尽管不再引用,却无法控制,它们占用的内存空间永远无法释放.
而Java自动内存管理,有时反而溺爱了Java程序员.只有真正来了解JVM如何管理内存,才能快速解决OOM问题.


参考资料:
《JAVA虚拟机精讲》, 高翔龙

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值