目录
一、GC算法
1.引用计数法:
比较古老而经典的算法,核心就是 在对象被其他所引用的时候计数器+1,当引用失效的时候-1。
缺陷:无法处理循环引用的情况,每次执行加减操作浪费系统性能。
2.标记清楚法:
分别标记和清楚两个阶段进行处理内存中的对象
缺陷:GC后的空间不是连续,造成空间碎片问题,不连续的内存空间工作效率较低
3.复制算法:
将内存空间分为两块,每次只使用其中一块,在gc时,将使用的那块内存中的存活对象复制到另一块内存中,然后清空当前这块 内存。 这样反复操作。
Java中新生代的s0和s1就是用的这个算法。
4.标记压缩法:
把存活的对象压缩到一边,然后进行gc
老年代用的就是这种算法。
新生代的回收频率高,但是每次回收耗时短;老年代回收频率低,但是耗时长。所以应该尽量减少老年代的GC。
二、分代和分区
1.分代算法:
根据对象的特点把内存分为N块,然后根据每个内存的特点使用不同的算法
2.分区算法:
将整个内存分为N多个小的独立空间,每个小空间可以独立使用,这样细粒度的控制一次回收多少个小空间和哪些小空间,而 不是对整个空间进行GC,从而提高性能,减少GC停顿时间
3.GC停顿现象:
GC执行的时候,大部分情况下会要求系统进入一个停顿状态,目的是终止所有的引用线程,这样系统就不会产生新的垃圾,同时保证了系统状态在某一个瞬间的一致性,也利于更好的标记垃圾对象。因此,在GC执行时会有一个停顿现象。
三、TLAB
Thread Local Allocation Buffer -> 线程本地分配缓存
TLAB是一个线程专用的内存分配区域,作用是加速对象分配。每一个线程都会产生一个TLAB。Java虚拟机用TLAB区来避免多线程冲突的问题,提高了对象分配的效率。TLAB框架一般不会太大,当大对象无法在TLAB上分配时,则会直接分配到堆上。
四、对象创建的过程
注意,在TLAB中分配失败的时候,会先判断是否在老年代分配,当不满足老年代分配的条件,才会去eden区分配。