下面是我在网上找的JVM内存图,非常直观,贴在下面,供大家学习……
下面分别介绍一下图中各个小方块的作用和存的东西,能力有限,如果有错误,希望大家指正
PC寄存器
一块很小的内存空间,用于记录下一条CPU要运行的指令,各个线程之间是独立拥有自己私人的PC寄存器的
- 当执行Java代码时:存放的Java字节码地址
- 当执行native方法时:则程序计数器为空
JAVA虚拟机栈
这也是是线程私有的内存空间,和线程一起创建,它保存方法的局部变量、部分结果,并参与方法的调用和返回。
- 栈的大小可以设置为动态扩展或者固定大小
- 可以使用 -Xss参数来设置栈的固定大小
- 如果超过固定大小,程序则会抛出StackOverflowError异常
- 如果设定为动态扩展,超过内存范围后,抛出OutOfMemoryError异常
栈帧
每个线程拥有独立的栈,而每个栈中的元素就称为栈帧,栈帧保存上下文数据。在栈帧中,存放的信息有方法的局部变量表、操作数栈、动态链接方法和返回地址等信息
出入栈对应的操作
- 入栈:表示方法的调用
- 出栈:表示方法的返回
局部变量表
- 存放方法的参数和局部变量
- 如果需要在方法内进行回收一个局部变量,可以将这个变量其设置为null或者在它超出范围后 ,对其进行 “复用”
- 方法外的局部变量会自动回收
本地方法栈
本地方法栈和Java虚拟机栈的功能很相似,JAVA虚拟机用于管理JAVA函数的调用,而本地方法栈用于管理本地方法的调用,本地方法栈不是用Java实现的,而是用C实现的
Java堆
JAVA运行时内存中最重要的部分,几乎所有的对象和数组都是在堆中分配空间的。java的堆分为新生代和老年代两部分,从开头的图中可以看出,他是被线程共享的
新生代
存放刚刚产生对象和年轻的对象,新生代有可以分为以下3个空间:
- eden : 伊甸园,即对象的出生地,大部分对象刚刚建立时,通常会存放在这里
- survivor space0 和 survivor space1 : 幸存者空间,又称为from space和to space,存放其中的对象是经历过一次垃圾回收了的,并幸存下来的对象或者数组
老年代 (the space)
如果对象一直没有被回收,生存的足够长,到了指定年龄的对象就会被移入老年代。
方法区 :
类加载器,将硬盘中的class文件加载到内存的class content中,然后按照JVM规范对class content进行解析,解析完后的对象(Class 对象),就放在方法区
- 方法区是一种规范,元空间是JDK8虚拟机中对方法区的一个具体的实现
- 可以通过MetaspaceSize、MaxMetaspaceSize调节大小(JDK8以前称为永久区)
- 将MetaspaceSize和MaxMetaspaceSize设置成一样大,可以防止内存抖动,建议设置为物理内存的 1 32 \frac{1}{32} 321
- JDK1.8以后,方法区的具体实现有永久区改为了元空间,而元空间数据是放在本地内存中,而非JVM内存,这样有利于存放更多更大的元数据
元数据
主要是class类中的各种信息,可以将他们分类如下:
类型信息
包括类的完整名称、父类的完整名称、类型修饰符(public/protected/private)、类型的直接接口类表
常量池
包括这个类方法、域等信息所引用的常亮信息,只要常亮池中的类没有被任何地方引用,就可以被回收。
域信息
包括域名称、域类型、域修饰符
方法信息
包括方法名称、返回类型、方法参数、方法修饰符、方法字节码、操作数栈、方法帧栈的局部变量区大小、异常表。
类加载器
加载过程
类的加载过程是由类加载器(ClassLoader)和它的子类来实现的,类加载器读取.class文件,然后产生Class对象,之后进过下面2个阶段:
- 连接阶段,这一阶段包括验证、准备(为静态变量分配内存并设置默认的初始值)和解析(将符号引用替换为直接引用)三个步骤
- JVM对类进行初始化,1) 先初始化父类;2) 执行这些初始化语句。
分类
- 根加载器(BootStrap):一般用本地代码实现,负责加载JVM基础核心类库(rt.jar)
- 扩展加载器(Extension):从java.ext.dirs系统属性所指定的目录中加载类库,它的父加载器是Bootstrap;
- 系统加载器(System):又叫应用类加载器,其父类是Extension。它是应用最广泛的类加载器。它从环境变量classpath或者系统属性java.class.path所指定的目录中记载类,
- 用户自定义加载器:默认父加载器是系统加载器。
回收的条件
- 所有该类的实例被回收
- 且装载该类的ClassLoader被回收
总结
上面的知识可能有些零散和晦涩,了解JVM的存放,可以让我们理解代码运行的逻辑,上面知识如有问题或者我有其他的新发现,我会及时更新