JVM的一些知识

1.什么是垃圾garbage?
没有任何引用指向的对象就是垃圾
2.判断哪些对象需要被回收?
1)引用计数法:
给对象添加一引用计数器,被引用一次计数器值就加一,当引用失效的时候,计数器值就减去1;当计数器为0时候,对象就是不可能再被使用的;
简单高效,但是无法解决对象之间相互循环引用的问题。
2)可达性分析算法
通过一系列的称为“GC’ Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连的时候,则证明改对象是不可用的,此算法解决了上述循环引用的问题。
GC Roots主要包括 线程栈变量、静态变量、常量流、JNI指针
3常见的垃圾清除的方法
1)标记清除
从图中可知,进行标记清理后,可以看出,清楚后的内存可用内存增加,但是清除垃圾后的内存地址不连接,出现垃圾碎片,当有大对象需要进行内存分配时,会因为找不到足够内存进行分配对象而造成垃圾回收,频繁的垃圾回收影响效率和性能
在这里插入图片描述

2)拷贝
所谓复制算法,就是把内存分为2块等同大小的内存空间(A和B),使用A进行内存的使用,当A部分的内存不足以分配对象而引起内存回收时,就会把存活的对象从A内存块放到B内存块中,后把A内存块中的对象全部清除,在B内存块中使用,当B内存不足以分配内存时,就会把B中存活的对象放到A内存块中,然后把B中对象全部清除,如此循环

缺点:使用这种方式可以避免出现空间碎片(内存中不连续的空间),不过会浪费一半的内存,降低空间的使用率。

在这里插入图片描述

3)标记压缩(标记整理)
从图中也可以看出,整理后的内存,避免了标记清除中的内存碎片的问题,也避免了复制算法中的内存浪费问题,当然,存在的问题就是效率问题了,一遍标记清除,一遍压缩空间,会比前2者的效率低。
在这里插入图片描述

参考博客:https://blog.csdn.net/cainiao_study/article/details/92711892(https://blog.csdn.net/cainiao_study/article/details/92711892)

4.对象的从出生到消亡
stack–》Eden–》S1–》S2(S1,S2反复直到年龄够了进入老年代)–》Old
1)MinorGC/YGC:年轻代空间耗尽时候触发
2)MajorGC/FullGC:在老年代无法继续分配空间时候触发,新生代、老年代同时
进行回收
3)对象的创建到消亡的图
在这里插入图片描述
什么是TLAB?
TLAB的全称是Thread Local Allocation Buffer,即线程本地分配缓存区,这是一个线程专用的内存分配区域。
由于对象一般会分配在堆上,而堆是全局共享的。因此在同一时间,可能会有多个线程在堆上申请空间。因此,每次对象分配都必须要进行同步(虚拟机采用CAS配上失败重试的方式保证更新操作的原子性),而在竞争激烈的场合分配的效率又会进一步下降。JVM使用TLAB来避免多线程冲突,在给对象分配内存时,每个线程使用自己的TLAB,这样可以避免线程同步,提高了对象分配的效率。
参考博客:https://blog.csdn.net/xiaomingdetianxia/article/details/77688945

补充:新建一个对象可能存在栈(涉及逃逸分析的知识,随着栈帧的弹出而消亡)、堆,TLAB中

5.内存的泄露和溢出
溢出:假设允许你用20M,但却超过20M,而且对象都活着
泄露:分配内存永远不会被回收

6JVM相关问题:
1)创建对象的过程:
申请一个空间—》初始化–》建立关联
2)DCL(Double Check Lock)与volatile的问题
DCL需要加volatile;
volatile作用:
a)线程可见性
b)防止指令重排
CPU比内存的速度快很多
cpu的乱序执行:cpu在进行等待的同时执行指令,是cpu乱序的根源;不是乱,而是为了提高效率
3)对象在内存中的存储布局
(64位虚拟机,8字节对齐,能被8整除)
markword、class pointer,实例数据、对齐(padding)
4)对象头具体包括什么(markword klasspointer)
a).identity hashcode
b)GC信息
c)锁的信息

5)对象怎么定位
a).句柄方式
b)直接指针
在这里插入图片描述
方式1的好处:不管堆中的实例对象地址是否发生改变,是否被垃圾回收,栈中的引用是不会发生改变的,改变的是堆中句柄池所保存的内存地址,则栈中的reference不需要被修改。
方式2的好处:引用直接指向堆内存的对象地址,相比使用句柄,减少了一次寻址过程,减少了一次性能开销,由于对象的访问定位频率非常高,节约了性能,速度快。
参考文章:https://blog.csdn.net/itcats_cn/article/details/80951929

6)对象怎么分配?

a).start–》尝试在“栈”上分配(好处:回收不需要垃圾回收器)
b)不能在栈上分配的,比较大的话,直接分配在老年代(通过fullGC才能回收);
c).如果没有很大的话,尝试分配在TLAB(即线程本地分配缓存区)
d)如果没有TLAB直接到Eden,需要线程同步,需要竞争,效率较低。
在这里插入图片描述

7)Object o = new Object()在内存占用多少字节
a).在开启指针压缩的情况下,markword 占用 8 字节,classpoint 占用 4 字节,Interface data 无数据,总共是12字节,由于对象需要为8的整数倍,Padding 会补充4个字节,总共占用16字节的存储空间。
b).在没有指针压缩的情况下,markword 占用 8 字节,classpoint 占用 8字节,Interface data 无数据,总共是16字节。
补充:
什么是指标压缩:
-XX:+UseCompressedOops 这个参数就是 JVM 提供的解决方案。通过压缩指针,占用的空间就会被压缩为原来的一半,节约空间。classpointer 参数大小就受到其影响。

参考文章:https://www.sohu.com/a/441291149_115128

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值