程序员

深入理解Java虚拟机(一)java运行时数据区域

2020-05-31  本文已影响0人  honehou

Java语言和虚拟机规范官方文档:https://docs.oracle.com/javase/specs/index.html

概述

Java虚拟机在执行程序的过程中,会把它管理的内存分为不同的数据区域。其中一些数据区域是在Java虚拟机启动时创建的,仅在Java虚拟机退出时才被销毁。有些数据区域是每个线程私有的。在创建线程时创建每个线程的数据区域,并在线程退出时销毁每个数据区域。如图所示:


image.png

程序计数器

程序计数器可以看作当前线程所执行的字节码的行号指示器。

Java虚拟机栈

Java虚拟机栈也是线程私有的,它是为虚拟机执行Java方法(也就是字节码)服务。

本地方法栈

本地方法栈是为虚拟机适用到的Native方法服务的。有的虚拟机(譬如sun HotSpot)直接就把本地方法栈和虚拟机栈合二为一。它抛出的异常与虚拟机栈类似。

Java堆

对大多数应用来说,Java堆是虚拟机管理的内存中最大的一块区域,是被所有线程共享的区域。官方文档中写道


The heap is the run-time data area from which memory for all class instances and arrays is allocated.

即所有的对象实例和数组都要在堆上分配。但随着JIT编译器发展,这并非绝对的。

方法区

方法区也是各个线程共享的内存区域,用于存储虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

官方文档中只规定了方法区这个概念,但没有规定具体的实现方式。在JDK1.7以前,HotSpot虚拟机主要使用永久代的方式来实现方法区,JDK1.8开始改为元空间。

运行时常量池

运行时常量池是方法区的一部分。Class文件中除了有类的版本、字段、方法、接口等描述信息外,还有一项就是常量池,用于存放编译期生成的各种字面量和符号引用,这部分内容在类加载后进入方法区的运行时常量池存放。

运行时常量池相比于Class文件常量池,具备动态性。Java并不要求常量一定只有编译期才能产生,运行期间也可能有新的常量放入池中。例如String类的intern()方法。

关于String类的intern方法,推荐一篇文章:https://tech.meituan.com/2014/03/06/in-depth-understanding-string-intern.html

上一篇 下一篇

猜你喜欢

热点阅读