SoftReference WeakReference区别避免混淆 软引用和弱引用的不同从源码注释入手以及手写测试避免记错混淆使用谐音记忆法加深印象..._情迁666的博客-程序员宅基地

技术标签: jvm  java  wap  powerdesigner  内存泄漏  

我的app很头疼,
有时候很容易记混淆,搞不懂哪个是内存不足才会回收,哪个随时可能被回收 哪个调用gc之后一定会回收,哪个是安卓推荐使用的..

那么先从安卓的源码开始,打开源码发现有一段注释证明软引用不推荐使用,

SoftReference

SoftReference的类注释:

* Soft reference objects, which are cleared at the discretion of the garbage
 * collector in response to memory demand.
 *
 * <p> Suppose that the garbage collector determines at a certain point in time
 * that an object is <a href="package-summary.html#reachability">softly
 * reachable</a>.  At that time it may choose to clear atomically all soft
 * references to that object and all soft references to any other
 * softly-reachable objects from which that object is reachable through a chain
 * of strong references.  At the same time or at some later time it will
 * enqueue those newly-cleared soft references that are registered with
 * reference queues.
 *
 * <p> All soft references to softly-reachable objects are guaranteed to have
 * been cleared before the virtual machine throws an
OutOfMemoryError .  Otherwise no constraints are placed upon the
 * time at which a soft reference will be cleared or the order in which a set
 * of such references to different objects will be cleared.  Virtual machine
 * implementations are, however, encouraged to bias against clearing
 * recently-created or recently-used soft references.
 *
 * <h3>Avoid Soft References for Caching</h3>
 * In practice, soft references are inefficient for caching. The runtime doesn't
 * have enough information on which references to clear and which to keep. Most
 * fatally, it doesn't know what to do when given the choice between clearing a
 * soft reference and growing the heap.
 *
 * <p>The lack of information on the value to your application of each reference
 * limits the usefulness of soft references. References that are cleared too
 * early cause unnecessary work; those that are cleared too late waste memory.
 *
 * <p>Most applications should use an {@code android.util.LruCache} instead of
 * soft references. LruCache has an effective eviction policy and lets the user
 * tune how much memory is allotted.
 *
 * @author   Mark Reinhold
 * @since    1.2
 */

从上面有几个关键英文单词Avoid Soft References for CachingMost applications should use an {@code android.util.LruCache}
避免使用, 大部分应用应该使用LruCache 这里说的很清楚,不是绝对,一定,不是必须使用LruCache, fragment的存储缓存是无法知道大小的,LruCache 我是不知道怎么整,翻阅了百度也找不到任何答案,测量obj大小的方法 也被谷歌删除了.fragment的存储到底用哪个好呢?

避免使用缓存缓存的软引用
*实际上,软引用对于缓存是无效的。运行时没有足够的信息,说明哪些要明确,哪些要保留。最
*致命的

All soft references to softly-reachable objects are guaranteed to have
 * been cleared before the virtual machine throws an
 * <code>OutOfMemoryError</code>.  O

guaranteed 保证
虚拟机保证在内存不足之前清理所有Soft references,我英语不好,应该是说内存不足的时候才会清除?还是说内存不足的时候一定会清除,但是不足的时候清除不清除呢?

WeakReference

注释:

/**
 * Weak reference objects, which do not prevent their referents from being
 * made finalizable, finalized, and then reclaimed.  Weak references are most
 * often used to implement canonicalizing mappings.
 *
 * <p> Suppose that the garbage collector determines at a certain point in time
 * that an object is weakly reachable</a>.  At that time it will atomically clear all weak references to
 * that object and all weak references to any other weakly-reachable objects
 * from which that object is reachable through a chain of strong and soft
 * references.  At the same time it will declare all of the formerly
 * weakly-reachable objects to be finalizable.  At the same time or at some
 * later time it will enqueue those newly-cleared weak references that are
 * registered with reference queues.
 *

 */

软引用验证,只有内存不足才会回收 如果回收了还是内存不足就鸡鸡了,这很适合用在fragment的缓存,因为内存还足够没必要回收.

下面是我测试SoftReference的程序,用eclipse测试最好不过了,调整最大内存为2M,初始化内存也为2M

改配置感受 紧

Launch configurations for 'TestReference.java'  ->Argments选项卡  Vm argments里面填写参数-Xmx2m -xms2m
image.png

测试软引用源代码

/**
     *Launch configurations for 'TestReference.java'  ->Argments选项卡  Vm argments里面填写参数-Xmx2m -xms2m   
     * @param args
     */
    public static void main(String[] args) {
        Object referent = new Object();
        java.util.List<String[]> list = new ArrayList<>();
        SoftReference<Object> softRerference = new SoftReference<Object>(referent);

        assertNotNull(softRerference.get());

        referent = null;

        int count = 0;
    
        while (softRerference.get()!=null) {
            System.out.println("obj!=null count:" + count);
            count++;
            String[] current=new String[1000];
            System.out.println("isempty:"+(softRerference.get()==null));
            list.add(current);
            for (int i = 0; i < current.length; i++) {
                
                current[i]=i+"";
            }
            
        
                        if(count%1000==0){
                        }
        }
        
        System.out.println("obj is recycle");

        /**
         * soft references 只有在 jvm OutOfMemory 之前才会被回收, 如果回收后发现还是内存不足,那么蛋蛋了
         * Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
    at java.util.Arrays.copyOfRange(Arrays.java:3664)
    at java.lang.String.<init>(String.java:207)
    at java.lang.StringBuilder.toString(StringBuilder.java:407)
    at TestReference.main(TestReference.java:29)
         * 
         */
        
    }

弱引用测试

static class MyObj {
        public MyObj(int no) {
            this.no = no;
        }

        public String[] getCurrent() {
            return current;
        }

        public void setCurrent(String[] current) {
            this.current = current;
        }

        public int getNo() {
            return no;
        }

        public void setNo(int no) {
            this.no = no;
        }

        String[] current = new String[1000];
        int no;

        @Override
        protected void finalize() throws Throwable {
            System.out.println("from:"+no+" :我被回收了我是hasCode:" + hashCode());
            super.finalize();
        }
    }
/**
     *Launch configurations for 'TestReference.java'  ->Argments选项卡  Vm argments里面填写参数-Xmx2m -xms2m   
     * @param args
     */
    public static void main(String[] args) {
        Object referent = new Object();
        java.util.List<WeakReference<MyObj>> list = new ArrayList<>();
        int loopindex = 0;
    System.err.println("=================================弱引用测试=================================");
            while(loopindex<200){
                
                String[] current=new String[500];
                for (int i = 0; i < current.length; i++) {
                    
                    current[i]=i+"";
                }
                MyObj obj=new MyObj(loopindex);
                obj.setCurrent(current);
                list.add(new WeakReference<TestReference.MyObj>(obj));
                if(loopindex%5==0&&loopindex>0){
                    System.out.println("start================"+loopindex+"================================");
                    System.out.println("即将调用调用主动gc,刚刚放进去的对象index:"+loopindex+"还在否:"+list.get(loopindex).get());
                    System.gc();
                    System.out.println("主动调用gc");
                    System.out.println("调用之后刚刚放进去的对象index:"+loopindex+"还在否:"+list.get(loopindex).get());
                    System.out.println("调用之后第一个还在否:"+list.get(0).get());
                    System.out.println("end================"+loopindex+"================================");
                }
                loopindex++;
            }
            
        
        

        /**

         * 
         */
        
    }

输出结果:

=================================弱引用测试=================================
start================5================================
即将调用调用主动gc,刚刚放进去的对象index:5还在否:[email protected]
主动调用gc
调用之后刚刚放进去的对象index:5还在否:[email protected]
调用之后第一个还在否:null
end================5================================
from:2 :我被回收了我是hasCode:1113044619
from:3 :我被回收了我是hasCode:1284526257
from:4 :我被回收了我是hasCode:1219485179
from:1 :我被回收了我是hasCode:229464714
from:0 :我被回收了我是hasCode:1915835994
start================10================================
即将调用调用主动gc,刚刚放进去的对象index:10还在否:[email protected]
主动调用gc
调用之后刚刚放进去的对象index:10还在否:[email protected]
调用之后第一个还在否:null
end================10================================
from:9 :我被回收了我是hasCode:1022006645
from:8 :我被回收了我是hasCode:178046742
from:7 :我被回收了我是hasCode:1837278661
from:6 :我被回收了我是hasCode:368688553
from:5 :我被回收了我是hasCode:1829164700
start================15================================
即将调用调用主动gc,刚刚放进去的对象index:15还在否:[email protected]4f
主动调用gc
from:10 :我被回收了我是hasCode:2018699554
调用之后刚刚放进去的对象index:15还在否:[email protected]
from:14 :我被回收了我是hasCode:2102444894
调用之后第一个还在否:null
from:13 :我被回收了我是hasCode:295178133
from:12 :我被回收了我是hasCode:1774992622
from:11 :我被回收了我是hasCode:822136971
end================15================================
start================20================================

测试调节初始化数组大小为500 或者1000 如果是1千,我们发现即使没有调用System.gc()它已经开始进行回收了,也就是稍微吃紧就会回收了,而改成500之后 第一次loop,没有回收等到调用gc执行完毕start-end逻辑后, 3 ,4,2,1,0都一个一个被回收了,从这里的消息也可以看出,回收虽然不会超大概率回收刚刚放进去的,但是也不会百分百先回收第一个,或者也许是日志打印和本地native消息不同步导致的??

看上去好像差不多,意思是在不定期检测 弱引用对象,那些不可达的进行清除.
但是没有说内存不足``oom```之前弱引用对象就一定已经被清除了。。

WeakHashMap 对于集合来说,用WeakHashMap也许更方便

软引用 手动调用System.gc回收的时候软引用不一定会回收, 但是弱引用一定会被回收,所以你是打算用软引用还是用弱引用呢?

为了加深印象避免混淆,我打算给他们取一个名字 ,软足弱鸡g ,也就是软引用是内存不足才会瘦 ,弱引用 gc马上会瘦
参考链接http://san-yun.iteye.com/blog/1683558https://baijiahao.baidu.com/s?id=1578867464445861486&wfr=spider&for=pchttp://www.cnblogs.com/skywang12345/p/3154474.html
测试案例参考http://wiseideal.iteye.com/blog/1469295

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u010042660/article/details/122189215

智能推荐

[知识图谱] 5.1-知识图谱开源数据获取_weixin_33806914的博客-程序员宅基地

学习知识图谱技术离不开数据,其实很多互联网公司都有公开的一些数据源供爱好使用。下面整理一些,仅供参考。国外知识图谱开源数据wikidata:包含所有维基数据实体列表freebase:类似维基百科,不同的时freebase是结构化数据webkb-2:允许Web用户在WebKB服务器机器上的一个大的知识库中存储、组织和检索知识dbpedia:它从维基百科的词条里撷取出结构化的...

在Jetson TX2上傻瓜式安装pytorch_comli_cn的博客-程序员宅基地_jetson tx2安装pytorch

0.前言将Jetson TX2刷机完毕之后因为要用到pytorch,所以就在网上查找如何安装,但试了好多方法都失败了,然后找到了NVIDIA官网的安装教程,网址:nvidia官方。1.步骤(1)查看版本是否符合上图是从所给网站上截下来的,可以看到支持安装JetPack4.2及以上版本的Nano,TX2,Xavier。而我的是安装有JetPack4.4 DP的TX2,是符合的。(2)选择合适的Pytorch版本从上面可以看到Pytorch v1.5.0和Pytorch v1.4.0都支持JetP

css实现div水平,垂直居中(两种方法)_LonlySnow的博客-程序员宅基地_cssdiv水平垂直居中

本文转载自https://www.cnblogs.com/jiekk/p/5802147.html,个人参考着实现了效果并总结如下,如果喜欢请给原作者评论分享~1.引言div的垂直水平居中应该是很常见的问题了,网上的方法也很多~总之就是要实现下图这个效果:我们慢慢来,先看看实现这个效果真正的难点(坑)在哪里~先不说具体的实现,很多人应该都熟悉margin:0 auto这个“...

3.4数据的输入输出_王星雨的博客-程序员宅基地

3.4 数据的输入输出一、输入输出的相关概念所谓输入输出是以计算机为主机而言的。C语言本身不提供输入输出语句,输入和输出操作是由C标准函数库中的函数来实现的。printf函数 和 scanf函数 不是 C语言提供的输入输出语句,也不是 C语言的关键字, 而只是 库函数的名字,函数声明在 stdio.h 这个库里面。为什么不提供输入输出语句呢? 答曰:为了使编译阶段不涉及计算机硬件操作,从而使编译系统简化,通用性强,可移植性好。各种C编译系统提供的系统函数库是各软件公司编制的。如果源程序中有

Python之Tornado开发硬件实时监控系统视频教程_星空资源网的博客-程序员宅基地_tornado 视频监控

  内容目录:  1-1_实战项目概述.mp4  1-2_http原理介绍.mp4  1-3_websocket原理介绍.mp4  1-4_硬件信息介绍.mp4  1-5_技术架构介绍.mp4  1-6_开发环境介绍.mp4  2-1_安装依赖包.mp4  2-2_构建项目目录.mp4  2-3_设计内存统计模型.mp4  2-4_设计交换分区统计模型.mp4  2-5_设计CPU统计模型.mp4  2-6_模型生成数据表.mp4  3-1_获取CPU信息.mp4  3-2_获取

【.NET Core项目实战-统一认证平台】第十二章 授权篇-深入理解JWT生成及验证流程..._weixin_30955341的博客-程序员宅基地

【.NET Core项目实战-统一认证平台】第十二章 授权篇-深入理解JWT生成及验证流程 原文:【.NET Core项目实战-统一认证平台】第十二章 授权篇-深入理解JWT生成及验证流程【.NET Core项目实战-统一认证平台】开篇及目录索引上篇文章介绍了基于Ids4密码授权模式,从使用场景、原理分析、自定义帐户体系集成完整的介绍了...

随便推点

OpenCV-判断OpenCV摄像头是否断开_weixin_33995481的博客-程序员宅基地

为什么80%的码农都做不了架构师?&gt;&gt;&gt; ...

common Lisp学习笔记(十三)_weixin_33805557的博客-程序员宅基地

lisp_chapter1313 Arrays, Hash Tables, and Proterty Lists13.2 array13.5 make-array13.6 string as vectors13.7 hash tables13.8 priority listlisp toolkit: room13.11 coerce1...

Excel VBA ——批量工作表重命名_weixin_30329623的博客-程序员宅基地

虽然平常在用excel 2010重命名工作表的时候,一般可能会用“双击工作表”的方法来重名,但是遇到大批量重名的时候就很麻烦。我的方法,先建一张新表,然后在第一列写好要命名的表名字,然后在VBE窗口里面输入代码Sub rename() '批量工作表重命名 Dim i As Integer For i = 1 To 5 Works...

java图书管理系统源码免费_Java图书管理系统 附源码_Mustafa先生的博客-程序员宅基地

内容来自用户:南望山下写代码目录题目简述-------------------------------- 01需求分析-------------------------------- 01数据结e68a84e8a2ad62616964757a686964616f31333433646431构-------------------------------- 01功能模块------------...

Word/Excel 在线预览_weixin_30485379的博客-程序员宅基地

前言近日项目中做到一个功能,需要上传附件后能够在线预览。之前也没做过这类似的,于是乎就查找了相关资料,.net实现Office文件预览大概有这几种方式:① 使用Microsoft的Office组件将文件直接转换为html文件(优点:代码实现最简单,工作强度最小。缺点:效果极差)②使用Microsoft的Office组件将文件转换为PDF格式文件,然后再使用pdf2swf转...

c语言安卓驱动开发,android驱动学习1-驱动开发流程(Android.mk)_weixin_39529128的博客-程序员宅基地

QQ:971586331软件环境:操作系统:windows 10IDE版本:Android Studio 3.4.2JAVA版本:jdk-8u221-windows-x64NDK版本:android-ndk-r20-windows-x86_64Kernel版本:linux 3.0开发板android版本:android 4.0.3硬件环境:开发板:itop-4412精英版本文内容:本文描述了如何...

推荐文章

热门文章

相关标签