• jvm学习SoftReference软引用回收时机


    说明

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

    源码

    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;
        }
    }

    软引用回收时机

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

    1.没有强引用时回收

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

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

    淘汰策略处理源码

    -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");
    }

    可能导致的问题

    使用第三方缓存 内部使用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

  • 相关阅读:
    struts2(五) s标签和国际化
    struts2(四) ognl表达式、值栈、actionContext之间的关系
    数据结构(一) 单链表的实现-JAVA
    struts2(三) 输入校验和拦截器
    struts2(二) 表单参数自动封装和参数类型自动转换
    struts2(一) struts2入门
    Java Web(十四) 编写MyBookStore项目的总结
    Java Web(十三) 使用javamail进行发送邮件,(使用QQ,163,新浪邮箱服务器)
    Java中反射机制详解
    Java Web(十二) commons-fileupload上传下载
  • 原文地址:https://www.cnblogs.com/LQBlog/p/16075841.html
Copyright © 2020-2023  润新知