美文网首页
每日一结——JVM内存模型

每日一结——JVM内存模型

作者: 奔向学霸的路上 | 来源:发表于2020-07-27 14:52 被阅读0次

JVM内存模型

JVM内存模型分为1.7与1.8版本(其中黄色代表线程共享,白色代表线程私有)

JVM内存模型图(1.7) JVM内存模型图(1.8) JVM运行时数据的直观感受

程序计数器

线程在运行期间,会想CPU进行时间片资源的争夺情况,假设现在A线程执行到了if判断,时间片突然发生了抢占,那么程序计数器会帮忙记录每个线程执行的下一条字节指令,等下次线程A拿到时间片继续执行(实际上就是记录当前线程执行到了什么位置,下一条指令是啥,下次接着从这个位置开始)。

  • 执行java方法:记录虚拟机正在执行的字节码指令地址。
  • 执行native方法:undefined
    5个区域唯一不会出现OOM的地方(OutOfMemoryError:所需内存超过虚拟机内存,在进行full gc后依然不够,会抛出OutOfMemoryError)

虚拟机栈

描述方法执行过程的内存模型,每个方法的执行过程就是它所对应虚拟机栈中的入栈出栈的过程,栈帧里面又会包括一些局部变量表(基本数据类型(byte、long、short、int、float、double、char、bolean)、对象引用类型),操作数栈,方法出口等信息

public class Test {

    public static void test() {
        int a = 1;
        int b = 2;
        int c = (a + b) * 10;
    }

    public static void main(String[] args) {
        test();
    }
}
上面代码对应的虚拟机栈图

局部变量表:abc
​操作数栈:像我们的程序后面都会被编译成这种字节码指令,而操作数栈将变量之间的运算入栈,然后存储计算结果,再出栈赋值给局部变量表
方法出口:代码中main()方法调用了test()方法,这时test()执行完成后,需要继续执行main()方法,方法出口记录了test()方法执行完成后的一个出口,也就是回到main()

本地方法栈

native修饰的方法,这些方法不由Java语言实现,而是由Java语言调用C++语言实现;跟虚拟机栈有些类似,只不过由native方法的线程栈帧。

方法区

方法区(又叫永久代),1.8叫元空间


方法区

存储已被虚拟机加载的类信息、常量、静态变量、即时编译后的代码等数据。

类信息:即 Class 类,如类名、访问修饰符、常量池、字段描述、方法描述等。 垃圾收集行为在此区域很少发生;不过也不能不清理,对于经常动态生成大量 Class 的应用,如 Spring 等,需要特别注意类的回收状况。

运行时常量池:用于存放编译器生成的各种字面量(就是代码中定义的 static final 常量)和符号引用,这部分信息就存储在运行时常量池中。

注:区分是存放在栈中还是方法区中,就看是(【栈】局部变量)还是(【堆/方法区】成员变量,静态变量,常量)
成员变量:在类范围内定义的变量,局部变量:在一个方法内定义的变量

元空间

JDK1.8后,方法区被叫做元空间,并且内存大小限制不限JVM的内存大小限制,而是直接使用计算机的直接内存,受计算机的内存大小限制。
1.8运行时常量池移到了堆。

主要存放我们程序中new出来的对象,提一点并非所有的对象都是在堆上进行分配,随着线程逃逸,标量替换等技术的发展,对象也有可能在栈上进行分配。

堆也是GC进行回收最主要的区域,容易出现OutOfMemoryError异常

新年代(young):老年代(old) = 1:2
其中新生代中,eden:survivor(From):survive(To)= 8:1:1

Minor GC:新建的对象会首先分配在eden区,Eden 区和 from 指向的 Survivor 区中的存活对象会被复制(此处采用标记 - 复制算法)到 to 指向的 Survivor区中,然后交换 from 和 to指针,以保证下一次 Minor GC时,to 指向的 Survivor区还是空的。
注:from与to只是两个指针,它们变动的,to指针指向的Survivor区是空的

Major GC:定义比较混乱,有点指的是Full GC有的指的是Old GC

Full GC:收集整个堆,包括young、old、永久代(1.8被移除,叫元空间)
Full GC触发条件有:

  • System.gc()方法的调用
  • 老年代空间不足
  • 方法区空间不足
  • 通过Minor GC进入老年代的平均大小大于老年代的可用内存
  • 由Eden区、From Space区向To Space区复制时,对象大小大于To Space可用内存,则把该对象转存到老年代,且老年代的可用内存小于该对象大小

举例题目

基于jdk1.8

public static void main(String[] args) {
        Integer a = new Integer(100);
        Integer b = new Integer(100);
        //比较的是对象,false
        System.out.println(a == b);
        //valueOf方法会走缓存,true
        System.out.println(Integer.valueOf(a) == Integer.valueOf(b));

        Integer c = 100;
        Integer d = 100;
        //true
        System.out.println(c == d);

        Integer e = 128;
        Integer f = 128;
        //false,缓存的范围是-128-127
        System.out.println(e == f);

        int h = 128;
        int i = 128;
        //true
        System.out.println(h == i);

        int j = 100;
        int k = 100;
        //true
        System.out.println(j == k);

        String l = new String("m");
        String m = "m";
        //false
        System.out.println(l == m);

        String n = "o";
        String o = "o";
        //true
        System.out.println(n == o);

        String p = "q";
        String q = new String("q");
        //true
        System.out.println(p == q.intern());
    }

java对String特殊对待,1. 存于常量池的字符串常量 2. 用于存储普通对象及字符串对象
String p = "q",jvm首先在常量池中查找有没有"q",如果没有在常量池中创建,如果有直接取;
String q = new String("q"),new就是在堆中创建一个新的String对象,不管"q"在内存中是否存在,都会在堆中开辟新空间,虽然new String()方法并不会把"abc” 加入到String constant pool中,但是可以手动调用String.intern(),将new 出来的字符串对象加入到String constant pool中。

参考:https://blog.csdn.net/toward_south/article/details/103024109
https://www.cnblogs.com/semi-sub/p/12827335.html

相关文章

  • 每日一结——JVM内存模型

    JVM内存模型 JVM内存模型分为1.7与1.8版本(其中黄色代表线程共享,白色代表线程私有) 程序计数器 线程在...

  • JVM内存模型(jvm 入门篇)

    概述 jvm 入门篇,想要学习jvm,必须先得了解JVM内存模型,JVM内存模型,JVM内存模型,JVM内存模型,...

  • JAVA内存模型笔记(JMM)

    JAVA内存模型 这里做的笔记是结合JVM中的java内存模型 和java并发编程艺术中讲的java内存模型 再结...

  • 浅析jvm与jmm模型结构与关系

    java内存模型(以下简称jmm)和java虚拟机模型(以下简称jvm)之间的关系,下面将详细讲述。 一 jvm结...

  • [Java多线程编程之八] Java内存模型

    一、Java内存模型 == JVM内存模型?   很多人都会认为Java内存模型就是JVM内存模型,但实际上是错的...

  • JVM问题及解答

    常见JVM问题 JVM内存模型,GC机制和原理。注意JVM内存模型与Java内存模型(JMM)不是同一个东西。JV...

  • JVM

    栈容量由-Xss指定深入理解JVM—JVM内存模型 JVM内存模型和JVM参数的关系

  • 高效并发

    从JVM的角度看一下Java与线程,内存模型,线程安全以及JVM对于锁的优化 硬件内存模型与JVM内存模型 硬件的...

  • JVM内存结构和Java内存模型

    最近看到两个比较容易混淆的概念:JVM内存结构和Java内存模型 JVM内存结构JVM内存结构或者说内存模型指的是...

  • jvm

    1.5.1JVM的内存模型 首先我们来了解一下JVM的内存模型的怎么样的: 基于jdk1.8画的JVM的内存模型-...

网友评论

      本文标题:每日一结——JVM内存模型

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