最佳实践:静态方法中对活动的弱引用
我需要在几个静态方法中引用一个活动。我很想知道避免内存泄漏的最佳实践。让我们举个例子:
示例 1:
static void hideKeyboard(Activity activity) {
WeakReference<Activity> activityReference = new WeakReference<>(activity);
// ... Call activityReference.get() when needed, check if null...
}
示例 2:
static void hideKeyboard(WeakReference<Activity> activityReference) {
// ... Call activityReference.get() when needed, check if null...
}
那么三个问题:
- 示例 1 或 2 有什么区别吗?
- 我还没有看到在 Thread 或 AsyncTask 的子类之外以这种方式调用方法。有什么理由吗?我错过了什么吗?
- 如果在这些方法之一的 Thread 或 AsyncTask 中使用弱引用,内存是否仍然会泄漏?
I need to reference an activity in several static methods. I'm curious to know the best practices to avoid memory leaks. Let's use examples:
Example 1:
static void hideKeyboard(Activity activity) {
WeakReference<Activity> activityReference = new WeakReference<>(activity);
// ... Call activityReference.get() when needed, check if null...
}
Example 2:
static void hideKeyboard(WeakReference<Activity> activityReference) {
// ... Call activityReference.get() when needed, check if null...
}
So three questions:
- Do example 1 or 2 make any difference?
- I haven't seen methods being called this way much outside of subclasses of
Thread
orAsyncTask
. Any reason why? Am I missing something? - If the weak reference is used in a
Thread
orAsyncTask
inside one of those methods, could memory still leak?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不,这没有区别。 Java中的垃圾收集工作了GC根的想法。如果变量是GC根或GC根引用(包括过渡性),则不能收集垃圾。函数的参数是GC root-直到函数返回其参数都无法收集。由于活动是您函数的参数,因此只要该函数在呼叫堆栈中,它就会是无法填充的。使用虚弱不会加快它的速度。
线程和异步箱(实际上只是围绕线程的包装器)略有不同。每个运行线程也是GC根。但是线程可以长寿,并且存在于对象的生命周期之外。在这里,使用弱率确实可能会有所帮助,因为没有其他原因需要保留(例如样本中的参数)。
您的示例2更好,这不是公然不必要的。但是我质疑为什么需要它。通常,在执行线程时,模式应该是:
这样做将阻止许多问题,例如需要检查弱参考。
No, it doesn't make a difference. Garbage collection in Java works on the idea of GC roots. If a variable is a GC root or references by a GC root (including transitively) it cannot be garbage collected. Parameters to a function are a GC root- until the function returns none of its parameters can be collected. Since Activity is a parameter to your function, it will be uncollectable as long as that function is in the call stack. Using a WeakReference won't speed it up.
Threads and AsyncTasks (which are just wrappers around Thread really) are slightly different. Every running thread is also a GC root. But threads can have a long lifetime and exist beyond the lifecycle of the object. Here, using a WeakReference does possibly help because there isn't another reason it needs to be kept around (like the parameter in your sample).
Your example 2 is a bit better, it isn't blatantly unnecessary. But I question why its needed. In general when doing a Thread the pattern should be:
Doing it like this will prevent a lot of problems like needing to check the weak reference a dozen times.
绝对没有理由在传递给方法的参数中使用
fealReference
,除非该参数已存储。如果仅在方法中使用该参数,则只需传递活动
参考即可。There is absolutely no reason to use
WeakReference
in a parameter passed to a method, unless this parameter is being stored. If the parameter is only used in the method, you can just pass in theActivity
reference.