2 垃圾回收

2.1 判断对象可以回收

  • 引用计数法

计算被引用的数, 如果被引用数为0 则进行回收

  • 可达性分析算法

jvm所使用的方法

根对象:肯定不能被当做垃圾回收的对象

垃圾回收前进行扫描, 该对象 是否是被根对象直接或者间接的引用, 如果是 则不能被回收 , 反之, 则可以被回收

image-20221124090455147

Memory Analyzer (Eclipse MAT)工具 帮助分析堆内存

1.先用jps查看进程id

2.jmap -dump:format=b,live,file=1.bin 进程id //抓取当前的进程内存快照转储成二进制文件

  • 四种引用

强引用

new 一个对象 是强引用


软引用

被GC Root对象间 接引用 , 内存不足时 容易被垃圾回收

软引用自身也是个对象, 当软引用引用的对象被回收时,自身会进入引用队列

image-20221125164546941


弱引用

只要发生垃圾回收时 会被直接回收

弱引用自身也是个对象, 当弱引用引用的对象被回收时,自身会进入引用队列


虚引用

创建直接内存时, 会创建一个Cleaner对象 来引用直接内存地址

当该对象被删除时 , 会将虚引用进入引用队列 而后被Unsafe里的freeMemory给释放掉


终结器引用

Object 父类有finallize方法 当重写了该方法, 并被垃圾回收时 被调用

当无直接引用该对象时, 会创建一个终结器引用 然后加入引用队列 再由优先级低的线程, 去查看终结器引用 然后调用finallize方法 而且第二次回收能够回收掉

这样效率很低 , 不推荐调用finallize方法去释放


2.2 垃圾回收算法

标记清除

先标记,后清除

优点:速度快

缺点:容易产生内存碎片

标记整理

存活较多

垃圾回收的时候,将空余空间间隙大的,进行移动

缺点:效率低

复制

存活较少的时候

新建一个同样大小的内存区,然后将老内存区的不需要回收的引用放到新的内存区中,然后清理整个旧的内存区,两者交换。

image-20230313221831920

2.3 分代回收

image-20230313223239285

新生代的垃圾回收 (新生代内存不够时) MinorGC:

存活对象用复制算法从伊旬园和From区复制到幸存区To 之后两个幸存区交换(装复制过来的对象的To区变成From区,清理完所有对象的From区变成的To区 —— 此时To区重新变成内存空的,From区装着此次MinorGC后幸存的对象), 对象寿命+1

当寿命到一定的数量(最大15次 因为存放这个的数的类型占据4bit 0-2^4-1 = 0 - 15) 那么就从幸存区放到老年代里

当MinorGC后新生代和老年代的内存都不够时,会触发一次Full GC , STW时间会变长

老年代使用的垃圾回收算法和新生代不同,会涉及到标记整理和标记清除 , 因此速度比较慢

MinorGC时会引发一次Stop the world 暂停用户线程

2.4 相关的VM参数

image-20230313224708318

一个线程的OOM不会导致主线程的终止

 posted on 2023-03-18 13:44    阅读(15)  评论(0编辑  收藏  举报