JVM学习(一)自动内存管理机制

博客中相关代码的git 地址:

JVM学习(一)自动内存管理机制地址:https://blog.csdn.net/qq_40119805/article/details/107399842
JVM学习(二)垃圾回收器和内存分配策略地址:https://blog.csdn.net/qq_40119805/article/details/107432575
JVM学习(三)虚拟机执行子系统地址:https://blog.csdn.net/qq_40119805/article/details/107456166
JVM学习(四)虚拟机类加载机制地址:https://blog.csdn.net/qq_40119805/article/details/107456166
JVM学习(五)JVM并发内存模型地址:https://blog.csdn.net/qq_40119805/article/details/107456166

本章主要介绍:
1.jvm内存分布和创建对象如何分配内存;

1.自动内存管理机制

1.1 运行时数据区

运行时数据区有5大块,分别为:堆,栈,方法区,程序计数器;其中栈分为本地栈和java栈;
按照线程私有 有程序计数器,栈*2;
按照线程共有 有 堆 ,方法区;

(1)程序计数器

简单的说程序计数器就是记录字节码指令执行到了哪里;
这是唯一一个在java虚拟规范中没有规定任何OOM的区域;

(2)java虚拟机栈

java栈是线程私有的,且他与线程生命周期相同;每个方法在执行时都会生成一个栈帧;栈帧中存储这程序方法的基本信息,比如 局部变量表,动态链接,方法出口等;
局部变量存放了编译器可预知的基本数据类型和引用变量;

(3)本地方法栈

本地方法栈和java虚拟机栈类似,只不过本地方法是为native服务的,java栈是为java服务的;

(4)java堆

java堆主要用来存放实例对象,基本所有的实例对象和数组都存在于堆中,另外java虚拟机规范中规定,java堆内存可以是不连续的,在逻辑上连续即可;

(5)方法区

用于存放已经加载的类信息,常量,静态变量,静态变量,即时编译后的代码等数据;

(6)运行时常量池

常量池署于方法区的一部分;用于存放各种字面量和类的符号引用;

2.HotSpot 虚拟机对象相关

2.1 对象的创建

(1)内存分配

当虚拟机遇到一条new指令时,他首先回到常量池中检测,是否能找到一个该类的一个符号引用,并检测是否已被加载和初始化,如果没用那会先执行类的加载过程。
类加载完成后会为新生对象分配内存,分配内存有两种方式:
1.指针碰撞:在gc堆使用标记整理算法时内存时规整的,使用的内存放在一边,未使用的放在另一边,这样每次分配对象只要将指针向另一侧移动相应的大小即可。
2.空闲列表:当gc堆使用标记清理算法时,堆内存时不规整的,所以需要额外维护一个列表来记录哪块内存使用了,那块内存未使用;

(2)分配对象的并发问题

对象的创建在虚拟机中是一个非常频繁的行为,哪怕只是修改一个指针所指向的位置,在并发情况下也是不安全的,可能出现正在给对象 A
分配内存,指针还没来得及修改,对象 B 又同时使用了原来的指针来分配内存的情况。解决这个问题有两种方案:
对分配内存空间的动作进行同步处理(采用 CAS + 失败重试来保障更新操作的原子性);
把内存分配的动作按照线程划分在不同的空间之中进行,即每个线程在 Java 堆中预先分配一小块内存,称为本地线程分配缓冲(Thread
Local Allocation Buffer, TLAB)。哪个线程要分配内存,就在哪个线程的 TLAB 上分配。只有 TLAB
用完并分配新的 TLAB 时,才需要同步锁。通过-XX:+/-UserTLAB参数来设定虚拟机是否使用TLAB。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值