引用详解与垃圾回收GC

引用详解.
概念:引用也是一个很模糊的概念,为了更加清晰的描述Java中的对象引用,在JDK1.2后,Java将引用分为4种,并且除了强引用外都有与之对应的Java类,都继承自Reference类。

  • 强引用(Strong Reference) : new的时候就是强引用,类似 0bject obj = new 0bject()
  • 软引用(Soft Reference):是用来描述一些有用,但非必须的对象引用,当内存特别紧张的时候,才会把这些对象列为回收目标进行回收,如果回收之后还是没有足够的内存,那么就会出现内存异常。对应Java类是SoftReference。一般用作缓存
  • 弱引用(weak Reference):也是用来描述一些非必须的对象引用,但是引用的强度要比软引用弱,不管内存是否充足,被弱引用关联的对象都将在下一次垃圾收集时被回收。对应Java类是weakReference,一般用于容器设计中,比如ThreadLocal中就是使用的弱引用。GC看到它,就会立刻将它干掉。
  • 虚引用(Phantom Reference):又称为是幽灵引用或者是幻影引用,是最弱的引用关系,一个对象是否有虚引用,完全不会对该对象的生存造成影响,也无法用虚引用来取得一个对象实例(无法使用get来获取)。
    对应“‘java.lang.ref.PhantomReference`,一般用于容器设计中。|
    为一个对象设置虚引用关联的唯一目的就是,在这个对象被cc回收的时候,虚引用会被存储到一个队列中,然后用户收到一个系统的关于这个引用的死亡通知,通俗的说也就是让对象死的明明白白吧。对应Java类是PhantomReference。主要管理堆外内存,比如NIO的直接内存,你可以设计一个变量,为其添加虚引用,当虚引被回收的时候,你会收到一个通知,当收到这个通知的时候,你去利用别的手段回收对应的堆外内存。GC看到它,就会立刻将它干掉。

垃圾回收算法
Mark-sweep算法
概念:Mark-sweep算法,标记-清除算法,他是最基础的垃圾回收算法,后续算法都是在这算法基础之上进行改进
描述:将内存进行遍历一次,有用内存标记为0,无用内存标记为1,再次进行遍历,将标记为1的清除;

  • 优点:在原内存上进行操作,不需要额外内存
  • 缺点:
    1:回收后内存不连续,会有内存碎片,进行大内存存储时可能找不到连续内存而再进行一次GC操作。
    2:两次遍历速度慢,效率不高,速度慢。
    在这里插入图片描述

Copy算法
概念:copy复制算法
描述:在内存中开辟一段相同连续内存,将原有需要保存数据进行复制到开辟空间中,删除原有内存。

  • 优点:复制代价小,速度快,不会产生内存碎片,
  • 缺点:
    1:需要两块相同大小的内存,对内存要求高
    2:对存活度高数据量大,就需要进行大量复制操作,对于存活时间长的一般不使用这种算法。
    在这里插入图片描述

Mark-Movee算法
概念: Mark-Move算法,标记-移动算法。
描述:从头到尾遍历区域,绿色标记e,黄色标记1,再次遍历,遇到e向前移动,遇到1直接清除。

  • 优点:整理后没有碎片,不需要双倍内存。
  • 缺点:但因在标记-清除算法的基础上增加了"移动",所以效率比标记-清除要低一些。

在这里插入图片描述

分代收集
概念:分代收集指的是根据实例年龄的不同而进行不同方式的回收,堆内存分为新生代和老年代,默认内存大小比例是1:2
,这个比例值是可以通过XX:NewRatio运行参数来动态设置的。

  • 新生代Young Generation :动态存储新new出来的对象
    新生代又被划分为3个区域:伊甸园‘Eden’和两个’ Survivor’幸存区:‘Survivor from’和Survivor to。
  • 'Eden ':实例一开始都在Eden区产生,当Eden满了,JVM执行一次minorGC,在整个新生代里面利用复制算法执行GC动作,88%-98%的实例会在这里直接死去,存活下来的幸存实例会被拷贝到某个Survivor区(假设为S1),且将幸存对象身上的计数器加1,Eden被清空,同时S2中存活下来的幸存实例也会被拷贝到S1,因为JVM规定必须保证至少有一个Survivor区是空的,另外,垃圾回收过程中年龄足够老的对象(计数器值过大)直接进入老年代。
  • Survivor :达到某个条件时,会将大于Survivor区的一半相对年龄大的实例都移入老年代,另外,在某次‘minorGC的过程中,年龄足够老的对象(计数器值过大)也会直接进入老年代。
    ·老年代old Generation:存储年龄稍大的实例,主要被MajorGC回收,HajorGC的回收速度比 minorGC低10倍,采用标记清除或者标记移动的算法,达到某个条件时JVM会执行一次FullGC,整体大回收。

垃圾收集器
概念:拉圾收集器是垃圾回收机制的具体实现,在JVM中,垃圾收集器可能存在一个或多个(单线程或多线程),它们在工作的时候,会短暂地暂停其他线程,这种情况被称为STW(Stop The word),减少STW时间是优化垃圾回收机制的重要指标。

垃圾收集器分类
概念:垃圾收集器的种类很多:

Serial

  • 一个单线程的新生代收集器,采取复制算法实现。
  • 在单CPU环境下,因为没有线程切换的开销,效率最高,STW控制在在几十到几百毫秒内。

Serial Old:

  • Serial收集器的老年代版本,也是一个单线程收集器,采取标记-整理算法。-它有个别名叫PS-MarkSweep。

ParNew

  • Serial收集器的多线程版本,收集算法、STM、对象分配的规则、回收策略等都与Serial收集器完全一样。
  • ParNew收集器的优势是更充分的利用CPU资源(多线程),缺点是是在单CPU 下,效果不一定会比Serial好。

PS 0ld :

  • PS-Scavenge收集器的老年代版本,采取标记-整理算法。
  • PS-Scavenge + PS-old的组合,对于多CPU环境,吞吐量要求高的环境是很适合的。

CMS:

  • CMS (Concurrent Mark Sweep),采取标记-清除算法,设计理念是尽可能地缩短STMw时间。
  • CND适用于一些特别重视响应速度的项目,但缺点是会产生大量的空间碎片。

G1:

  • 目前最高端的收集器,采取标记-整理算法,不会产生内存碎片,并且也可以精准地控制STw的时
  • 对于新生代和老年代都是适用的,优先回收垃圾最多的区域。

垃圾收集器常见组合:

  • SerialGC = Serial ‘Serial 0ld,JVM客户端默认使用它。
  • ParNewGCT =ParNew + Serial old
  • ConcMarkSweepGC = ParNew+CMS+ Serial 01d
  • ParallelGdC=PS Parallel + Serial old (PS MarkSweep),JVM服务端默认使用它。
/**
 * @author liusichang
 */
public class GarbageCollectorTest {
    //查看当前版本垃圾回收器
    @Test
    public void myGarbageCollector(){
        for (GarbageCollectorMXBean e: ManagementFactory.getGarbageCollectorMXBeans()){
            System.out.println(e.getName());
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值