「这是我参与2022首次更文挑战的第14天,活动详情查看:2022首次更文挑战」
2、垃圾回收算法
标记-清除
定义:标记清除算法顾名思义,是指在虚拟机执行垃圾回收的过程中,先采用标记算法确定可回收对象,然后垃圾收集器根据标识清除相应的内容,给堆内存腾出相应的空间
- 这里的腾出内存空间并不是将内存空间的字节清0,而是记录下这段内存的起始结束地址,下次分配内存的时候,会直接覆盖这段内存
缺点:容易产生大量的内存碎片,可能无法满足大对象的内存分配,一旦导致无法分配对象,那就会导致jvm启动gc,一旦启动gc,我们的应用程序就会暂停,这就导致应用的响应速度变慢
标记-整理
标记-整理 会将不被GC Root引用的对象回收,清楚其占用的内存空间。然后整理剩余的对象,可以有效避免因内存碎片而导致的问题,但是因为整体需要消耗一定的时间,所以效率较低
复制
将内存分为等大小的两个区域,FROM和TO(TO中为空)。先将被GC Root引用的对象从FROM放入TO中,再回收不被GC Root引用的对象。然后交换FROM和TO。这样也可以避免内存碎片的问题,但是会占用双倍的内存空间。
3、分代回收
回收流程
新创建的对象都被放在了新生代的伊甸园中
当伊甸园中的内存不足时,就会进行一次垃圾回收,这时的回收叫做 Minor GC
Minor GC 会将伊甸园和幸存区FROM存活的对象先复制到 幸存区 TO中, 并让其寿命加1,再交换两个幸存区
再次创建对象,若新生代的伊甸园又满了,则会再次触发 Minor GC(会触发 stop the world, 暂停其他用户线程,只让垃圾回收线程工作),这时不仅会回收伊甸园中的垃圾,还会回收幸存区中的垃圾,再将活跃对象复制到幸存区TO中。回收以后会交换两个幸存区,并让幸存区中的对象寿命加1
如果幸存区中的对象的寿命超过某个阈值(最大为15,4bit),就会被放入老年代中
如果新生代老年代中的内存都满了,就会先触发Minor GC,再触发Full GC,扫描新生代和老年代中所有不再使用的对象并回收
GC 分析
大对象处理策略
当遇到一个较大的对象时,就算新生代的伊甸园为空,也无法容纳该对象时,会将该对象直接晋升为老年代
线程内存溢出
某个线程的内存溢出了而抛异常(out of memory),不会让其他的线程结束运行
这是因为当一个线程抛出OOM异常后,它所占据的内存资源会全部被释放掉,从而不会影响其他线程的运行,进程依然正常