美文网首页程序员
Java1.8内存模型

Java1.8内存模型

作者: Trade丿Life | 来源:发表于2020-05-19 21:19 被阅读0次

    PC寄存器

    • 每个线程都有一个程序计数器,是线程私有的,就是一个指针,指向方法区中的方法字节码

    方法区

    • 方法区被所有线程共享

    • 静态变量,静态方法,常量,类信息(构造方法,接口定义),运行时的常量池

    • static,final,Class类模板信息

    方法栈

    public class MethodTest {
        public static void main(String[] args) {
            MethodTest methodTest = new MethodTest();
            methodTest.stackMethod_1();
            methodTest.stackMethod_2();
    
        }
        void stackMethod_1() {
            System.out.println("入栈");
        }   
        void stackMethod_2() {
            System.out.println("入栈");
        }
    }
    
    • image-20200517160755368.png
    • 栈内存,主管程序的运行,生命周期和线程同步

    • 线程结束,栈内存也就释放,栈不存在垃圾回收

    • 程序正在执行的方法一定在栈顶

    • 8大基本类型 + 对象引用 + 实例方法

    栈溢出

    • 方法无限相互调用,超过栈的存储空间

    对象创建简化版内存模型

    • image-20200517165651898.png

    对象创建过程

    • image-20200517170459644.png

    • 一个JVM只有一个堆内存,堆内存的大小是可以调节的
    • 堆内存分为三个区域
      1. 新市区
      2. 老年区
      3. 永久区

    堆内存空间

    • image-20200517194543774.png
    • From区和To区会相互交换

    永久区的变化

    • 这个区域的是常驻内存,用来存放JDK自身携带的Class对象,interface元数据,存储的一些环境和类信息,这个区域不存在垃圾回收,关闭JVM就会释放
      1. jdk1.6之前:永久代,常量池是在方法区
      2. jdk1.7:永久代,常量池放入堆中
      3. jdk1.8后:无永久代,常量池在元空间

    各区域详解

    程序计数器

    • 字节码解释器改变程序计数器来依次读取指令,实现顺序执行,循环,选择,异常处理

    • 记录当前线程执行的位置,便于线程切换回来的时候知道上次运行的位置

    Java虚拟机栈

    • 主要存放8大基本类型,对象引用
    • 方法的出口信息

    本地方法栈

    • 则为虚拟机使用到的Native方法

    • 存放对象实例
    • 新生代(Eden空间,From Survivor,ToSurvivor)和老年代
    • JDK1.8移除整个永久代,取而代之的是元空间的区域(永久代使用的是堆内存空间,元空间使用的是物理内存)

    方法区

    • 加载的类信息,常量,静态变量

    运行时常量池

    • 用来存放编译期生成的各种字面量和符号引用

    • 字面量(文本字符串,被声明为final的常量值,基本数据类型的值)

    • JDK1.7之后,常量池方法区中移到了堆中

    JDK1.8内存模型

    • image.png
    • JDK1.8后永久代移除,变为元空间

    • 方法区概念保留,转移到了元空间

    • 常量池移到了堆种

    • 方法区移到本地内存的原因:IO操作更快

    参考

    • 参考自狂神的B站视频
    • JavaGuide的内存分析

    相关文章

      网友评论

        本文标题:Java1.8内存模型

        本文链接:https://www.haomeiwen.com/subject/popiohtx.html