深刻剖析Java虚拟机内存结构

深刻剖析Java虚拟机内存模型

JVM总体架构

JVM总体架构以下:java

经过编写代码来分析整个内存区域架构

public class Math {
    public static final Integer CONSTANT = 666;

    public int compute(){
        int a = 1;
        int b = 2;
        int c = (a + b) * 10;
        return c;
    }

    public static void main(String[] args) {
        Math math = new Math();
        math.compute();
    }
}

对上述代码的class文件进行javap - c Math.class > Math.txtjvm

javap -c是对代码进行反汇编函数

获得Math.txt文件命令行

对compute方法进行分析:code

public int compute();
    Code:
       0: iconst_1 //  将int型(1)推送至栈顶
       1: istore_1 //  将栈顶int型数值存入第二个本地变量
       2: iconst_2 //  将int型(2)推送至栈顶
       3: istore_2 //  将栈顶int型数值存入第三个本地变量
       4: iload_1 //   将第二个int型本地变量推送至栈顶
       5: iload_2 //   将第三个int型本地变量推送至栈顶
       6: iadd //      将栈顶两int型数值相加并将结果压入栈顶
       7: bipush        10 // 将单字节的常量值(-128~127)推送至栈顶
       9: imul // 将栈顶两int型数值相乘并将结果压入栈顶
      10: istore_3 // 将栈顶int型数值存入第四个本地变量
      11: iload_3 // 将第四个int型本地变量推送至栈顶
      12: ireturn

上面程序,在JVM中的运行时区域以下:对象

操做的操做暂时的数据存放到操做数栈blog

main()的局部变量表存放对象的引用地址。ip

动态连接

动态连接就是当咱们这个程序运行main方法时,当执行math对象额compute方法时,去compute方法执行,compute方法算是符号引用,找到符号引用所在的方法体,执行。内存

执行javap -v Math.class > Math.txt获得字节码文件

找到main方法所在的位置

public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=2, args_size=1
         0: new           #2                  // class com/tugohost/jvm/Math
         3: dup
         4: invokespecial #3                  // Method "<init>":()V
         7: astore_1
         8: aload_1
         9: invokevirtual #4                  // Method compute:()I
        12: pop
        13: return
      LineNumberTable:
        line 17: 0
        line 18: 8
        line 19: 13
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      14     0  args   [Ljava/lang/String;
            8       6     1  math   Lcom/tugohost/jvm/Math;

其中

9: invokevirtual #4 // Method compute:()I

这一行表示,main函数中的math对象调用compute方法,

再往上找,找到常量池

找到

#4 = Methodref          #2.#33         // com/tugohost/jvm/Math.compute:()I

再找#2#33

#2 = Class #32 // com/tugohost/jvm/Math
#3 = Methodref #2.#31 // com/tugohost/jvm/Math." ":()V

因此这个过程就是动态连接的过程。

本地方法栈

本地方法栈就是存储native方法

若是Eden区放满,会minor GC,若是还存活的对象,会放到From区生命值+1,同理会放到To区生命值+1,若是生命值大于某个值(能够本身设置),会放到老年代

经过写一个死循环代码来看看堆中垃圾收集器的工做:

public class HeapTest {
    byte[] a = new byte[1024 * 100]; // 100Kb

    public static void main(String[] args) throws InterruptedException {
        ArrayList<HeapTest> heapTests = new ArrayList<>();
        while (true){
            heapTests.add(new HeapTest());
            Thread.sleep(10);
        }
    }
}

经过命令行jvisualvm打开Java visualVM

若是老年代满了触发Full GC。若是Full GC对老年代没有用,即老年代中没有无用的对象时,出现OOM效果。

相关文章
相关标签/搜索