GC回收 - 内存分配
基于算法理论和实际实现,即先构建策略算法,然后采用具体的实现体,去实现。
1、明确哪些需要被回收。
算法为:
(1)计数算法:一个对象被使用一次,计算加一,释放减一,最后对象计算为零标记回收。针对对象之间的互相调用就会出现问题。A对象调用B对象,B调用A,但实际不需要,就出现内存问题。
(2)可达算法:采用 GCRoots为起点,向下检索,没有检索的对象标记回收。(使用的)
2、回收策略:
(1)标记-清除:将标记的对象直接清除
(2)复制:针对标记清除后,内存区间不连贯,采用将内存分为两块,只使用其中一块,清除时,直接将引用对象放到另一块,原使用区直接清除。(新生代使用)
(3)标记-整理:标记-将存活对象移动另一端,然后将之前全部清理掉。(老年代使用)
3、实际实现:
首先理解JVM堆内存区域:分为新生代和老年代。其中新生代对象迭代频繁,老年代相对稳定些。分别对应JVM内存中的栈堆。
新生代采用复制的回收策略,其中,新生代分为:一个eden区和两个survivor区,默认8:1:1。可直接使用为:eden区和其中一个survivor区。另一个survivor区用于GC回收时,直接将引用对象存放里面。但有时会出现这个区域装不下的问题,此时会触发,直接将这些对象放到老年代。
老年代采用标记-整理策略,接收对象来源于类的对象和用于回收的survivor区装不下时的对象,还有当新生代GC次数(年龄)大于15时,会将对象直接转入老年代;或者,相同年龄对象大小大于survivor内存的一般时,回想大于等于这个年龄对象转入老年代。
新生代GC为:minor GC
老年代GC为:FULL GC
以上为个人理解,若有出入,请多多指证。