Java虚拟机内存结构——JDK1.8

一、Java虚拟机整体结构

二、JVM内存结构

    (1)线程私有部分

      1.本地方法栈:登记native方法,在执行引擎执行时加载本地方法库

      2.程序计数器:就是一个指针,存储指向下一条指令的地址 ,由执行引擎读取下一条指令,

是一个非常小的空间,可以忽略不计

      3.java栈:Java线程执行方法的内存模型,一个线程对应一个栈,每个方法在执行的同时,

都会创建一个栈帧(用于存储局部变量表,操作数栈,动态链接,方法出口等信息),不存在

垃圾回收问题,只要线程一结束该栈就会释放,生命周期和线程一致

class Math{
	public static final Integer CONSTANT_1 = 666;

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

	public static void main(String[] args) {
		Math math = new Math();
		System.out.println(math.math());
		System.out.println("end");	
	}
}

 只要启动一个线程都会创建下面的结构,即程序计数器,Java栈,本地方法栈 都是线程私有的

    因为栈数据结构的特点是先进后出,所以当Math.java启动后,

   先创建main()-栈帧,放进Java栈,然后执行math()方法,再创建一个math()-栈帧放进Java栈,

   当math()方法执行完成后,math()-栈帧后放进去,先被被弹出;

   math()方法执行完成后,main方法才能执行完成,main()-栈帧先放进去,后被弹出

         A:局部变量表 ----- > 

                              int a = 1; int b = 2; ....

        B:操作数栈 ----- > 执行 运算 (a + b) * 10 的数据过程

          

        C:动态链接:在方法中new 一个对象,这个对象放入会放入堆中,这里会存在一个指针指向堆中的对象

        D:方法出口

注意:Java 针对Java栈区域规范了两种异常

        1)当线程请求的栈深度大于虚拟机栈所允许的深度,就会抛出StackOverFlowError异常

        2)若虚拟机可动态扩展,当无法申请到足够的内存空间,就会抛出OutOfMemoryError异常

通过jvm参数 -Xss指定栈空间,空间大小决定栈调用深度

     执行命令:1)javac Math.java把java文件变成class字节码文件

                       2)javap -c Math.class把字节码文件反汇编成指令文件

  (2)线程共享部分

         1.方法区:静态变量 + 常量 + 方法信息(构造方法/接口定义) + 运行时常量池 都存在方法区中有一个别名叫

非堆(Non - Heap)

         2.堆:虚拟机启动的时创建,用于存放对象实例,几乎所有对象(包含常量池)都在堆上分配内存,当对象无法在该空间申请到内存时,将抛出OutOfMemoryError异常;同时也是垃圾收集器管理的主要区域。可通过-Xmx -Xms参数来分别指定最大堆和最小堆

(3)Java栈+堆+方法区的交换关系

    HotSpot是使用指针的方式来访问对象

   Java堆中会存放访问类元数据的地址

   reference存储的就直接是对象的地址

猜你喜欢

转载自blog.csdn.net/lihongtai/article/details/83212058