Android内存泄漏与静态最终

Der*_*ekD 4 static android memory-leaks

问题是使用静态最终常量显然会导致内存泄漏:我一直在搜索有关如何在Android应用中导致内存泄漏的信息.一个大问题是对常量使用private static final.显然,应该如何定义常量.但是静态最终意味着它在旋转后挂起并意味着无法清除活动.

显然我误解了一些事情.我知道将变量放在Application上下文中允许它们在不引起问题的情况下挂起.

作为关于内存泄漏的一般性问题:有很多关于内存泄漏的信息,但我找不到任何能够清楚地总结所有信息的内容.任何完全解释的建议.

Bob*_*ke4 12

此信息不正确.使变量静态final不会因为标记为static final而导致任何类型的内存泄漏.这并不是说你不能通过这样做来创建内存泄漏.您要确保避免的一件事是创建一个类型为context的静态变量(例如activity).当您创建对上下文的静态引用时,您可能会创建内存泄漏.静态变量意味着整个应用程序和该类的实例只有该变量的一个副本.它还意味着它将保留在内存中,直到它被明确清除或应用程序关闭.静态变量是类级变量,不附加到对象的任何特定实例.例如,当您创建'public static final string myString ="Hello"'时,您将永远不会导致内存泄漏.这种定义常量的方式实际上会节省内存与使用'public final string myString ="Hello"',因为如果没有静态,将创建一个内存位置来为该类的每个实例存储该字符串,而不是只为所有实例提供一个副本使用.


Chr*_*Bye 5

在Java中,静态变量存在于堆上,并在其类加载时分配.实例变量的垃圾收集资格与其实例相关联.

使用value-type(int,bool,double等)静态变量不会泄漏类的实例.当您允许非值类型的静态变量时,您可以泄漏这些静态变量引用的任何内容.

考虑一个简单的类

public class Activity extends Context {
    static int willNotLeakActivity = 0;
    static Context mayLeakActivity = new Context();

    //if you call activityA.leakyMethod(activityA); you will leak activityA
    public void leakyMethod(Context context){
        mayLeakActivity = context;
    }

    //this method won't leak the instance
    public void safeMethod(int arg){
        willNotLeakActivity = arg;
    }
}
Run Code Online (Sandbox Code Playgroud)

如果在静态变量中保留对Activity对象的引用(即使引用类型为Context),则会泄漏Activity对象.

请记住,Android不是在真正的JVM上运行,而是在Dalvik VM上运行,所以你的结果在理论上可能会有所不同,但我会惊讶地发现Dalvik在GC资格方面有所不同(我的避风港)我自己遇到任何问题.

编辑 - 再看一下这个问题,我认为这可能会清除一些理解:只要可以通过GC根目录中的以下参考链来访问对象,就不会有资格进行垃圾收集.活动对象被实例化并且通过Android进程正常保持活动(我假设它至少与某些东西一起保持活着static void main(string[] args).

一旦系统调用yourActivityInstance.onDestroy()并释放refefence,该对象就有资格进行GCed(随后是它引用的所有对象),除非您的活动实例可以通过另一个引用从GC根目录到达.如果此引用的持续时间超过应该保持的时间(读取:无限期),则表示您已泄漏此对象,因为GC无法确定它是否可以安全地释放泄漏对象的资源.

无论如何保持此引用(静态或非静态,最终或非最终)都无关紧要.只要可以从GC根目录(至少是静态方法中的本地和范围内变量,加载类中的静态字段)到达对象,您就会泄漏.