垃圾回收算法
java垃圾回收机制:
java的一大优点,就是引入了垃圾回收机制,避免了程序员需要对每个对象进行手动的垃圾回收,但是也会造成一个小麻烦,就是不能自主的进行垃圾回收(虽然System.gc()可以启动垃圾回收,但是由于java语言规范,不一定会执行)。
常用的垃圾回收算法:
1.标记-清除,直接将需要清除的垃圾进行标记,当内存不足时,对标记过的垃圾进行回收。优点:对象不需要移动;缺点:清除效率低,而且会产生大量不连续的内存碎片,如果此时大对象进入,会由于内存不足,而导致触发多次GC
2.标记-复制,将整个内存划分为两个区域,只使用一个区域进行存储对象,当内存不足时,将要保存的对象,复制到另一个区域中,再对之前的区域进行GC。优点:按顺序分配内存即可,实现简单;缺点:可用内存变为原来的一半,对象存活率高的话,就会频繁的进行复制。
3.标记-压缩,将需要回收的对象标记后,将所有存活的对象全部挤压到内存到一端去,再对剩余的内存空间进行GC。优点:解决了清除算法的内存碎片问题,但是需要对象的移动,一定程度上降低了效率。
4.分代收集算法,更加对象的存货周期,将内存划分为年轻代,老年代,永久代。一般再年轻代中执行标记复制算法,在老年代中执行标记压缩算法。
常见的垃圾回收器:年轻代:serial,parnew,parallel scavenge 老年代:serial old,parallel old,cms 全局收集:g1 注意:serial表示串行收集,直接执行stw,单一执行垃圾回收;而parallel表示并行,执行stw,多线程执行垃圾回收,cms和g1是并发,系统和垃圾回收同时执行,系统不会暂停
jdk8中使用的垃圾回收器是parallel scavenge和parallel old;而jdk11中使用的是g1;
垃圾回收内存分配:一般分为年轻代和老年代,内存占比1:2;而在年轻代中,还分为Eden(伊甸区)和to survivor区和from survivor区,占比为8:1:1
垃圾回收原理:当对象进入回收时,先进入Eden区,如果对象过大,在Eden区中没有足够内存存储时,触发GC,Eden区和to survior的存活对象就被复制到from survivor区中去,然后进行gc,(如果内存过大,直接进入年老代),在这个过程中to和form会不断进行变化,并且由于对象的对象头信息中会记录GC年龄分带,但年龄大于15后(是由于对象头信息中记录会有四个bit位来表示年龄,而4个bit位最大值就是15,所以一般默认是15,可以设置),对象就会从年轻代转移到年老代。