【JVM:一】Java运行时数据区域

Java运行时数据区域

在这里插入图片描述

1 程序计数器(Program Counter Register)

线程私有。
程序计数器是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器。在多线程环境下,每条线程都需要一个独立的程序计数器,各个线程之间计数器互不影响,独立存储,所以将其设计为线程私有。
程序计数器不会发生OutOfMemeryError的错误情况。因为程序计算器所维护的就是下一条待执行的命令的地址,所以不存在OOM。

2 Java虚拟机栈(Java Virtual Machine Stack)

线程私有。
虚拟机栈描述的是Java方法执行的线程内存模型:每个方法被执行的时候Java虚拟机都会同步创建一个栈帧,用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法被调用直至执行完毕的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。
如果线程请求的栈深度大于虚拟机所允许的栈深度,将抛出StackOverFlowError异常。由于HotSpot不支持栈容量的动态扩容,所以只要线程成功的申请到了栈空间,就不会发生OOM,如果申请失败仍会OOM。

3 本地方法栈

线程私有。
与Java虚拟机栈的区别是,它是为虚拟机使用到本地方法服务。也会发生栈溢出异常和OOM。

4 Java堆

线程共享。
用于存放对象实例的内存区域。是垃圾收集器管理的内存区域。
如果在Java堆中没有内存完成实例分配,并且堆也无法再扩展时,Java虚拟机将会抛出OOM异常。

4.1 字符串常量池

JDK1.7之前,字符串常量池再永久代中。首次调用intern方法,会将改字符串复制到字符串常量池中,并返回池里的引用。
JDK1.7之后,字符串常量池移到了堆中。首次调用intern方法,如果字符串常量池中没有该串,就会在池中创建一个对该字符串的引用并返回。

5 方法区

线程共享。
方法区与Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据。JDK7时,把原本放在永久代的字符串常量池、静态变量等移除,到了JDK8,完全废弃了永久代的概念,改为在本地内存中实现的元空间来代替。
相对而言,垃圾收集行为在这个区域的确是比较少出现的,但并非数据进入了方法区就如永久代的名字一样“永久”存在了。这区域的内存回收目标主要是针对常量池的回收和对类型的卸载。
当方法区无法满足新的内存分配需求时,将抛出OOM异常。

5.1 运行时常量池

运行时常量池是方法区的一部分。Class文件有一项信息是常量池表,用于存放编译期生成的各种字面量与符号引用,这部分内容将在类加载后存放到方法区的运行时常量池中。
Java语言并不要求常量一定只有编译期才能产生,运行期间也可以将新的常量放入池中。如String类的intern()方法。
当常量池无法再申请到内存时会抛出OOM异常。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值