JVM内存模型

一 先看jvm的知识结构

这里写图片描述## 二 jvm的内存区域

1. jvm内存区域

jvm一共由 java堆 方法区 Java栈 本地方法栈 pc计数器-------------这五个是运行时的数据区 还有类加载器 直接内存 垃圾回收器 执行引擎组成

1.1 Java堆
  1. 堆是分配实例的地方,是所有线程共享的 eg:A a = new A(); 对象A的分配的空间就是在堆中分配的
  2. 几乎所有的对象分配内存都是在堆中分配的,但是也有在栈中分配(逃逸分析时候会在栈中分配)
  3. 垃圾回收主要是针对堆进行的
1.2 方法区

方法区也可以理解为堆的一部分,只是存储的数据类型不一样,堆中存储的是对象实例的数据,例如 类中A的字段,方法,话句话说 举个例子:

class A{
	int a = 1;
	static int b = 4;
	final int c  = 5;
	public A(){};
	public int getA(){
		return a;
	}
}

这个类的结构就是存储在堆中,而关于这个类的信息就是存储在方法区中

也就是方法区中存储的是类信息,静态量 常量 JIT编译的代码等数据,,外加运行时的常量池

上述A中 这个类是类还是抽象类,还是接口,父类是什么,常量是什么,类变量是什么,类的名字是什么,都存储在方法区

1.3 pc计数器

pc计数器 记录的是将要执行的下一条指令的地址 如果是在执行本地方法中的代码 pc计数器的值为null

1.4 jvm栈
  1. 栈是方法执行的内存模型,每个方法的执行和退出就是栈帧的出栈和入栈的过程
  2. 每个方法对应一个栈帧,栈帧会存储方法的参数(操作数栈),局部变量表 返回值类型,动态链接(解析引用)
1.5 本地方法栈

功能同java栈 区别就是Java栈执行的是Java的方法 本地方法栈执行的是本地方法

2. 运行时的常量池

2.1 运行时的常量池存储在方法区中
2.2 主要存储 类变量 常量 编译期身生成的各种字面量和符号引用 字面量就是 String a =“字面量”; a就是符号引用, a的值就是字面量
2.3 String.intern() 从常量池中返回值

3. 对象的创建过程

 首先判断这个类是否加载过
 美加载过就加载,加载过就通过指针碰撞或者空间列表的方式在堆中分配内存
 初始化字段的默认值 int的是0  boolean的是false 。。。。
 设置对象头信息 hashcode 分代年龄 锁信息等
 按我们程序的要求初始化 也就是 int a = 9;设置a的值是9  上一步是设置a的值是0

4. 对象的内存布局

对象有三部分组成 对象头,数据区,对齐填充

4.1 对象头

对象头部分记录对象的hash值,分代年龄,锁信息 偏向锁偏向的线程等等 对于数组来说还存储数组的长度 i那位对象的大小jvm是可知的,但是数组有多少个对象就不知道了;还会存储类型指针就是这个对象的类的信息----也就是指向方法区

4.2 实例数据

就是对象中的实际数据了

4.3 对齐填充

这部分是可有可无的,jvm要求对象的大小必须为8的整数倍,如果大小是就没必要填充了,否则就填充

5. 对象的访问定位

栈中的引用怎么找到队中对应的实例呢?

  1. 通过句柄访问 假设 A a = new A();
    在堆中有个区域专门记录了实例A的位置 我们叫他句柄 句柄记录了实例的位置 以及类型的位置(一个指向堆,一个指向方法区)
  2. 直接使用指针访问------栈中记录实例在堆中的地址
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值