JVM学习-SoftReference软引用回收时机(十四)

1. 说明

以前学习各个引用类型的区别,最近在看一个JVM参数-XX:SoftRefLRUPolicyMSPerMB 对软引用有更深入的了解
在这里插入图片描述

2. 源码

public class SoftReference<T> extends Reference<T> {
    /**
     * 由垃圾回收器负责更新的时间戳
     */
    static private long clock;

    /**
     * 在get方法调用时更新的时间戳,当虚拟机选择软引用进行清理时,可能会参考这个字段。
     */
    private long timestamp;

    public SoftReference(T referent) {
        super(referent);
        this.timestamp = clock;
    }

    public SoftReference(T referent, ReferenceQueue<? super T> q) {
        super(referent, q);
        this.timestamp = clock;
    }

    /**
     * 返回引用指向的对象,如果referent已经被程序或者垃圾回收器清理,则返回null。
     */
    public T get() {
        T o = super.get();
        if (o != null && this.timestamp != clock)
            this.timestamp = clock;
        return o;
    }
}

3. 软引用回收时机

软引用会在内存不足的时候进行回收,但是回收时并不会一次性全部回收,而是会使用一定的回收策略

1.没有强引用时回收

2.根据限制时间clock-timestamp<=heap空间内存*-XX:SoftRefLRUPolicyMSPerMB(默认1000) true为不回收 false为回收

注意源码可以看出get和初始化都会将timestamp更新成clock的值

4. 淘汰策略处理源码

-XX:SoftRefLRUPolicyMSPerMB

就HotSpot虚拟机而言,常用的回收策略是基于当前堆大小的LRU策略(LRUCurrentHeapPolicy),会使用clock的值减去timestamp,得到的差值,就是这个软引用被闲置的时间,如果闲置足够长时间,就认为是可被回收的。

bool LRUCurrentHeapPolicy::should_clear_reference(oop p,
                                                  jlong timestamp_clock) {
  jlong interval = timestamp_clock - java_lang_ref_SoftReference::timestamp(p);
  assert(interval >= 0, "Sanity check");

  if(interval <= _max_interval) {
    return false;
  }

  return true;
}

_max_interval计算公式

void LRUCurrentHeapPolicy::setup() {
  _max_interval = (Universe::get_heap_free_at_last_gc() / M) * SoftRefLRUPolicyMSPerMB;
  assert(_max_interval >= 0,"Sanity check");
}

5. 可能导致的问题

使用第三方缓存 内部使用sorftRefrece封装.缓存占比太大 可能导致长时间得不到回收 而导致大量fullgc

或者是大量反射 反射后的元数据就是通过sorfRefrece封装参考:https://www.sohu.com/a/124124072_494943

我们线上设置的-XX:SoftRefLRUPolicyMSPerMB=0 理论上每次GC都会回收。

参考:

  • https://www.cnblogs.com/mfrank/p/10154535.html

  • https://www.cnblogs.com/mfrank/p/10154535.html

  • https://article.pchome.net/content-2026644.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值