在阿帕奇和谐的JarURLConnectionImpl Android的内存泄漏? [英] Android memory leak in Apache Harmony's JarURLConnectionImpl?

查看:205
本文介绍了在阿帕奇和谐的JarURLConnectionImpl Android的内存泄漏?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我工作的一个Android应用程序,我们正在调查的内存使用。

I'm working on an Android app and we're investigating memory use.

看着从HPROF堆转储,我们看到近2M(我们堆的22%)在JarURLConnectionImpl静态缓存被使用:

Looking at a heap dump from hprof, we're seeing nearly 2M (22% of our heap) being used in a static cache in JarURLConnectionImpl:

纵观<一href="http://svn.apache.org/repos/asf/harmony/enhanced/java/trunk/classlib/modules/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/jar/JarURLConnectionImpl.java">source code代表JarURLConnectionImpl 的,看来条目被添加到静态jarCache变量,但永远不会被删除。

Looking at the source code for JarURLConnectionImpl, it appears that entries are added to the static jarCache variable, but never removed.

如果这是真的,他们永远不会被删除,这让我觉得作为一个潜在的内存泄漏。

If it's true that they're never removed, that strikes me as a potential memory leak.

这是泄漏?是否有修补程序或解决方法吗?

Is this a leak? Is there a fix or workaround?

推荐答案

下面是一个丑陋的解决方法:

Here's an ugly workaround:

private static HashMap<URL,JarFile> jarCache;


static {
    try {
        Class<?> jarURLConnectionImplClass = Class.forName("org.apache.harmony.luni.internal.net.www.protocol.jar.JarURLConnectionImpl");
        final Field jarCacheField = jarURLConnectionImplClass.getDeclaredField("jarCache");
        jarCacheField.setAccessible(true);
        //noinspection unchecked
        jarCache = (HashMap<URL, JarFile>) jarCacheField.get(null);
    } catch(Exception e) {
        // ignored
    }
}

然后,定期运行以下命令:

Then, periodically run the following:

    // HACK http://stackoverflow.com/questions/14610350/android-memory-leak-in-apache-harmonys-jarurlconnectionimpl
    if( jarCache!=null ) {
        try {
            for (
                final Iterator<Map.Entry<URL, JarFile>> iterator = jarCache.entrySet().iterator(); iterator.hasNext(); ) {
                final Map.Entry<URL, JarFile> e = iterator.next();
                final URL url = e.getKey();
                if (Strings.toString(url).endsWith(".apk")) {
                    Log.i(TAG,"Removing static hashmap entry for " + url);
                    try {
                        final JarFile jarFile = e.getValue();
                        jarFile.close();
                        iterator.remove();
                    } catch( Exception f ) {
                        Log.e(TAG,"Error removing hashmap entry for "+ url,f);
                    }
                }
            }
        } catch( Exception e ) {
            // ignored
        }
    }

我运行它的活动创造所以它会被执行每次创建我的活动一次。丑陋的HashMap的入口似乎并没有得到重新创建所有的时候,但它似乎重新出现偶尔,所以它是不够的只是运行此code一次。

I run it on activity creation so it gets executed every time one of my activities is created. The ugly hashmap entry doesn't seem to get recreated all that often, but it DOES seem to reappear occasionally, so it's not sufficient to just run this code once.

这篇关于在阿帕奇和谐的JarURLConnectionImpl Android的内存泄漏?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆