在Java中使用WeakReferences

Mr *_*r H 0 java performance memory-management weak-references

我一直试图WeakReference在我的Android项目中使用,但我从来没有取得任何成功.现在我真的需要它,因为我正在处理旧设备,我必须尽可能地保持内存清洁.

无论如何,我有一个数组,其中包含大约1000个不同字符串列表.我需要加载它,然后在其中找到一个字符串.

这就是我目前使用它的方式:

String[] campaignList = context.getResources().getStringArray(R.array.campaignList);
WeakReference<String[]> weakCampaignList = new WeakReference<String[]>(campaignList);
Run Code Online (Sandbox Code Playgroud)

这是正确的使用方式WeakReference吗?如果是,那么我不明白的是阵列正在水合,String[]然后我把它传递给了WeakReference.那么这是不是意味着我在分配给一个阵列的内存上有2个点?或者我完全误解了这个WeakReference概念?

我在所有资源中发现的一个非常好的资源就是这个:

http://neverfear.org/blog/view/150/Strong_Soft_Weak_and_Phantom_References_Java

编辑:

我的代码没有问题.只需要知道我在性能方面是否正确.

for (int i = 0; i < weakCampaignList.get().length; i++) {
  Log.d(TAG,"weakCampaignList: "+weakCampaignList.get()[i]);
}
Run Code Online (Sandbox Code Playgroud)

我的整个方法

public static String getTheCampaign(String country, Context context) {
        String campaign = "";
        campaign = "annual_subscription_" + country;

        String[] campaignList = context.getResources().getStringArray(
                R.array.campaign_list);

        ArrayList<WeakReference<String>> weakCampaignList = new ArrayList<WeakReference<String>>();
        for (String s : campaignList) {
            weakCampaignList.add(new WeakReference<String>(s));
        }

        if (country.equals("") || country.isEmpty()) {
            campaign = "annual_subscription_us";
        } else {
            for (int i = 0; i < weakCampaignList.size(); i++) {
                if (weakCampaignList.get(i).get().contains(campaign)) {
                    campaign = weakCampaignList.get(i).get();
                    return campaign;
                } 
            }
        }
        return campaign;
    }
Run Code Online (Sandbox Code Playgroud)

Sam*_*ell 5

在诸如Java之类的垃圾收集语言中,弱引用通常用于防止静态或长期存在的对象导致永远不会释放内存.例如,假设您的应用程序包含一个单例类ClipboardMonitor,该类跟踪用户按下的最后一个文档Ctrl+ C.

class ClipboardMonitor {
    static Document lastDocument;

    // return the last document where Ctrl+C was pressed
    static Document getLastDocument() {
        return lastDocument;
    }

    static void copyCommand(Document document) {
        lastDocument = document;
    }
}
Run Code Online (Sandbox Code Playgroud)

在此实现中,如果用户按下Ctrl+ C然后关闭文档窗口(但不关闭应用程序),该lastDocument字段将继续保持对文档的引用,并且垃圾收集器无法回收该内存.弱引用可以解决该问题.

在下面的修改代码中,静态字段lastDocument变为弱引用,因此即使用户按下Ctrl+ C并且文档被分配给该字段,垃圾收集器也可以在文档关闭后回收文档内存.

class ClipboardMonitor {
    static WeakReference<Document> lastDocument;

    // return the last document where Ctrl+C was pressed, or null if
    // that document was closed and the garbage collector has already
    // reclaimed the memory
    static Document getLastDocument() {
        WeakReference<Document> weakDocument = lastDocument;
        return weakDocument != null ? weakDocument.get() : null;
    }

    static void copyCommand(Document document) {
        lastDocument = new WeakReference<Document>(document);
    }
}
Run Code Online (Sandbox Code Playgroud)

这个例子强调了关于弱引用的最重要的一点:弱引用本身并不能节省内存.相反,它们用于解决在以垃圾收集语言编写的应用程序中可能导致明显内存泄漏的特定类型的问题.如果您的应用程序设计不需要使用弱引用来解决特定的设计限制,那么添加弱引用只会产生以下一种(或多种)后果:

  1. 增加应用程序的内存要求
  2. 增加应用程序的CPU要求
  3. 当您仍然需要使用的对象意外地收集垃圾时,引入难以重现的错误

原始帖子中的代码不包含确定是否需要使用弱引用的信息或证据,也不提供显示其正确用于解决应用程序特定约束的必要信息.以上信息是关于弱参考的一般评论,可以帮助您了解如何继续.

编辑:根据您发布的更新方法,在您的情况下似乎不需要弱引用.它们没有提供任何好处,并且至少导致上面列表中的问题1和2.根据特定的垃圾收集器实现,它们也可能导致问题3(NullPointerException当您尝试调用时抛出一个问题contains).