GC简介:
GC(garbage collection,内存自动回收),是Java区别于C++的一个特点。
底层实现是GC跟踪正在使用的对象,并且将剩余的对象做标记稍后清除,从而实现内存的自动管理。
GC Root 简介
JVM中通过可达性算法判断对象是否可被回收。
基本思路是从GCRoots的活跃引用为起始点,从这些集合节点开始向下搜索,搜索所走过的路径成为引用链。
如果一个对象和GC rotts之间没有任何链,说明对象可被回收。
JVM Heap内存模型
Young-Eden
Eden进一步划分为驻留一个或者多个的ThreadLocalAllocationBuffer(简称TLAB)。
TLAB是线程独占的。
如果TLAB中没有空间进行对象分配时,对象分配操作将尝试在Common Area中申请空间。
如果整个Eden都没有足够的空间,那么会出发young GC。
如果Young GC后仍然没有足够的内存,会尝试在Old Generation(Tenured)中申请空间。
当内存回收器收集Eden的时候,会遍历所有相对于GC Roots
可达的对象,并且标记它们是活对象,这一阶段称为标记阶段。
Young-Survivor Spaces-Survivor0
标记阶段完成后,Eden中所有存活的对象会被复制到Young-Survivor Spaces-Survivor0 的其中一块空间。复制阶段完成后,整个Eden被认为是空的,可以重新用于分配更多其他的对象。这里采用的GC算法称为标记-复制(Mark and Copy) 算法。
Young-Survivor Spaces-Survivor1
年轻代的所有存活的对象(包括Eden和非空的from幸存者区域中的存活对象),都会被复制到to幸存者区域,这个过程完成之后,to幸存者区域会存放着活跃的对象,而from幸存者区域会被清空。接下来,from幸存者区域和to幸存者区域的角色会交换,也就是下一轮YGC触发之后存活的对象会复制到from幸存者区域,而to幸存者区域会被清空,如此循环往复
OldGeneration(Tenured)
经历15次young GC后,如果对象仍然存活,会被复制到Young-Survivor Spaces-Survivor1。
这个区域很少进行GC。
老年代的GC算法一般是移动对象以最小化内存碎片。
Metaspace(Java8之前的Permanent Generation)
Java8中已经移除了永久代,新增了一块内存区域Metaspace(元空间),Class
定义信息等元数据目前是直接加载到元空间中。
元空间分配在机器本地内存(native memory
),它和承载Java对象的堆内存是隔离的。
GC类型
Partial GC
Young GC
:只收集young gen的GC。Old GC(Major GC)
:只收集old gen的GC,目前只有CMS的concurrent collection是这个模式。Major GC的速度一般比Minor GC慢10倍以上,STW事件更长。如果Major GC还不足,会报OOM。Mixed GC
:收集整个young gen以及部分old gen的GC,目前只有G1有这个模式。
Full GC
-
收集整个堆,包括young gen、old gen、perm gen(如果存在的话)等所有部分的模式。
FullGC的触发条件:
1)命令调用System.gc()时,系统建议执行Full GC,但不是必然执行。
2)老年带空间不足。
3)方法区空间不足等。
常见GC算法
mark and copy
mark and compact
mark and sweep
常见GC收集器
Serial
Serial,Stop the world, copying collector which uses a single GC thread.
Serial Old
Serial Old,Mark-sweep-compact collector, that uses a single GC thread.
Parallel Scavenge(并行捡):
A stop the world, copying collector which uses multiple GC threads.
高吞吐量为目标, 即减少垃圾收集时间(就是每次垃圾收集时间短,但是收集次数多),让用户代码获得更长的运行时间。
Parallel Old GC
ParNew
CMS(Concurrent Mark Sweep):
A mostly concurrent, low-pause collect, it has 4 phases: initial mark, concurrent mark, remakr, conccurent sweep。