深入理解JVM之运行时数据区域

运行时数据区域包括程序计数器,java虚拟机栈,本地方法栈,方法区和堆。其中,java虚拟机栈,本地方法栈,程序计数器是每个线程私有的。

程序计数器

可以看作是当前线程执行到的字节码的行号指示器。对于Java的多线程,为了使程序每次切换后能够恢复到正确的执行位置,因此每一个线程必须要有自己独立的程序计数器。如果线程执行的是Java方法,记录的是正在执行的虚拟机字节码指令的地址(如果正在执行的是本地方法则为空)。

Java虚拟机栈

线程私有。线程每执行一个方法,都会在该线程的虚拟机栈中,创建一个栈帧,用于存储局部变量表、操作数栈、常量池引用等信息。方法调用直至执行完成的过程,就对应着一个栈帧在 Java 虚拟机栈中入栈和出栈的过程。

 

局部变量表 存放了各种基本数据类型,对象引用和ReturnAdress(你需要返回的字节码指令的地址)。

两种异常情况:

  • 当线程请求的栈深度超过最大值,会抛出 StackOverflowError 异常;
  • 栈进行动态扩展时如果无法申请到足够内存,会抛出 OutOfMemoryError 异常。

可以通过 -Xss 这个虚拟机参数来指定每个线程的 Java 虚拟机栈内存大小:

java -Xss512M HackTheJava

 本地方法栈

跟虚拟机栈差不多,只不过它是为Native Method服务的。

一个Native Method就是一个java调用非java代码的接口。一个Native Method是这样一个java的方法:该方法的实现由非java语言实现,比如C。

Native Method详解:https://blog.csdn.net/wike163/article/details/6635321

                                   https://www.cnblogs.com/HDK2016/p/7226840.html

存放对象实例。所有线程共享。

OOM异常

方法区

用于存放已被加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。在HotSpot中,也叫方法区为永久代。因为GC分代收集拓展到方法区。方法区主要是废弃类和常量的收集,对于方法区,也可以选择不进行垃圾回收。

OOM异常。

运行时常量池

运行时常量池是方法区的一部分。

Class 文件中的常量池(编译器生成的字面量和符号引用)会在类加载后被放入这个区域。

运行时常量池具有动态性,除了在编译期生成的常量,还允许动态生成,例如 String 类的 intern()。

String.intern()

如果常量池中存在当前字符串, 就会直接返回当前字符串. 如果常量池中没有此字符串, 会将此字符串放入常量池中后, 再返回。

详解:https://tech.meituan.com/2014/03/06/in-depth-understanding-string-intern.html

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值