这些不可不知的JVM知识,我都用思维导图整理好了 (2)

局部变量表存放了编译期可知的各种Java虚拟机基本数据类型、对象引用(reference类型,它并不等同于对象本身,可能是一个指向对象起始址的引用指针,也可能是指向一个代表对象的句柄或者其他与此对象相关的位置)和returnAddress 类型(指向了一条字节码指令的地址)。

image-20210214142724540

2.3、本地方法栈

本地方法栈(Native Method Stacks)与虚拟机栈所发挥的作用是非常相似的,其区别只是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的本地(Native) 方法服务。

Hot-Spot虚拟机直接把本地方法栈和虚拟机栈合二为一。

与虚拟机栈一样,本地方法栈也会在栈深度溢出或者栈扩展失败时分别抛出StackOverflowError和OutOfMemoryError异常。

2.4、Java堆

对于Java应用程序来说,Java堆(Java Heap)是虚拟机所管理的内存中最大的一块。Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,Java 世界里“几乎”所有的对象实例都在这里分配内存。

Java堆是垃圾收集器管理的内存区域,因此一些资料中它也被称作“GC堆”。

从回收内存的角度看,

Java 堆,由年轻代和年老代组成,分别占据 1/3 和 2/3。

而年轻代又分为三部分,EdenFrom SurvivorTo Survivor,占据比例为 8:1:1,可调。

需要注意的是这些区域划分仅仅是一部分垃圾收集器的共同特性或者说设计风格而已,而非某个Java虚拟机具体实现的固有内存布局,HotSpot里面已经出现了不采用分代设计的新垃圾收集器。

image-20210213193521527

Java堆既可以被实现成固定大小的,也可以是可扩展的,不过当前主流的Java虚拟机都是按照可扩展来实现的(通过参数-Xmx和-Xms设定)。如果在Java堆中没有内存完成实例分配,并且堆也无法再扩展时,Java虚拟机将会抛出OutOfMemoryError异常。

2.5、方法区(JDK1.8移除)

方法区(Method Area)与Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载 的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据。

在JDK1.8以前,HotSpot使用永久代来实现方法区,所以某些场合也认为方法区和永久代是一个概念。

在JDK 6的 时候HotSpot开发团队就有放弃永久代,逐步改为采用本地内存(Native Memory)来实现方法区的计划了,到了JDK 7的HotSpot,已经把原本放在永久代的字符串常量池、静态变量等移出,而到了 JDK 8,终于完全废弃了永久代的概念,改用在本地内存中实现的元空间(Meta- space)来代替,把JDK 7中永久代还剩余的内容(主要是类型信息)全部移到元空间中。

如果方法区无法满足新的内存分配需求时,将抛出OutOfMemoryError异常。

2.6、运行时常量池

运行时常量池(Runtime Constant Pool)是方法区的一部分——在JDK1.8已经被移到了元空间。

运行时常量池相对于Class文件常量池的一个重要特征是具备动态性,Java语言并不要求常量一定只有编译期才能产生,也就是说,并非预置入Class文件中常量池的内容才能进入运行时常量池,运行期间也可以将新的常量放入池中,这种特性被开发人员利用得比较多的便是String类的 intern()方法。

2.7、直接内存

直接内存(Direct Memory)并不是虚拟机运行时数据区的一部分。

显然,本机直接内存的分配不会受到Java堆大小的限制,但是,既然是内存,则肯定还是会受到本机总内存(包括物理内存、SWAP分区或者分页文件)大小以及处理器寻址空间的限制。

元空间从虚拟机 Java 堆中转移到本地内存,默认情况下,元空间的大小仅受本地内存的限制。jdk1.8 以前版本的 class 和 JAR 包数据存储在 PermGen 下面 ,PermGen 大小是固定的,而且项目之间无法共用,公有的 class,所以比较容易出现 OOM 异常。

升级 JDK 1.8 后,元空间配置参数,-XX:MetaspaceSize=512M XX:MaxMetaspaceSize=1024M。

3、JVM中的对象

上面已经了解Java虚拟机的运行时数据区域,我们接下来更进一步了解这些虚拟机内存中数据的其他细节,譬如它们是如何创建、如何布局以及如何访问的。以最常用的虚拟机HotSpot和最常用的内存区域Java堆为例,了解一下HotSpot虚拟机在Java堆中对象分配、布局和访问的全过程。

3.1、对象的创建

Java对象创建的大概过程如下:

image-20210214114717010

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wppsyz.html