`

jvm垃圾回收

    博客分类:
  • jvm
 
阅读更多


垃圾回收方法:

引用计数器:如果一个变量引用一个对象,就对该对象引用加1,当对象超过生存期或被重置为其他值,减1,到零时垃圾回收,缺陷:循环引用:父类引用子类,子类又引用父类将永远不会被回收。

跟踪收集:

从根结节点开始引用检查,利用标记标识被引用对象,未标记清除。

拷贝收集:

针对内存碎片,根据算法标记被引用对象,并从现在内存区域拷贝到一个大的空白区域,原区域整体回收,该方法利用引用句柄指向堆对象,这样对象的地址改变时更新句柄指向,缺陷:拷贝过程将停止程序运行,性能代价比较大。

按代收集:

按对象的生命周期长短区分对象:年轻代,老年代,年轻代每次都会被回收,如果年轻代对象几次回收后还存在,转入老年代,老年代没有年轻代回收的频率那么多,这样避免了拷贝收集的性能消耗,可以分为多个不同层次的代。

自适应收集:

由jvm决定当前堆状态使用哪种回收机制,根据堆状态切换到某个回收机制。

火车算法

将堆为分不同块,块是排序的,块连接起来组成集合,集合也是排序的,块相当于车厢,集合相当于火车,垃圾回收将先回收最小集合的最小块,这里的最小是指序号,以些类推来回收每个块的垃圾对象,这种算法是基于代的,所以一个块中的对象可能是被老年代引用的,将把该对象移到老年代所有的集合中(火车),如果对象的引用来自于其他集合中非老年代的块中就把对象移到该块中,如果该块以满将在该集合的尾部增加块来保存该对象,当处理完成非老年代引用的对象及老年代引用的对象后,其它的对象就只有集合本身的对块的引用了,将这些对移到集合中最后的块中,最后回收整个块的内存。

引用的分类

强引用

强引用是使用最普遍的引用。如果一个对象具有强引用,那垃圾回收器绝不会回收它。当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题,比如一个变量指向一个对象这就是强引用。

软引用

如果一个对象只具有软引用,则内存空间足够,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存,软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收器回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。

Myobj obj=new Myobj();

SoftReference ref=new SoftReference(obj);//创建软引用

如果ref没有被内存回收可以通过如下找到它

Myobj refObj=(Myobj)ref.get(); //否则返回null

软引用可以与ReferenceQueue关联,在回收软引用后软引用对将会被保存在ReferenceQueue中

ReferenceQueue queue=new ReferenceQueue();

SoftReference ref=new SoftReference(refObj,queue);

判断是否被回收

MyReference是我自定义的SoftReference

if(((MyReference)queue.poll())!=null){

//清楚MyReference

}

弱引用


弱引用与软引用的区别在于:只具有弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。不过,由于垃圾回收器是一个优先级很低的线程,因此不一定会很快发现那些只具有弱引用的对象。
弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被垃圾回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中。

WeakHashMap就是一个弱引用实现类


put方法可以插入弱引用,在remove方法或垃圾回收执行前弱引用将一直保存在weakhashmap中。

weakhashmap也有一个queue使用与软引用的相同。

影子引用

保存即将被回收的对象,垃圾回收器将处理将被回收的对象保存在影子引用队列中,所以影子引用必须与一个队列一同使用,可以利用影子引用完成在回收之前想完成的工作。


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics