4

如果我有这样的代码:

public class MyActivity extends Activity 
{

private SingletonClass singletonInstance;

...

@Override
protected void onCreate(Bundle savedInstanceState) 
{
    singletonInstance = SingletonClass.getInstance();
}

...
}

我的理解是 Activity 将保持活动状态,因为它具有对静态实例的引用,因此无法被 GC 处理。但是,它似乎不会给我的应用程序带来任何问题。我不了解 GC 还是这真的是内存泄漏,我应该避免保留对我的单例类的引用?

4

2 回答 2

1

研究了您的疑问,我确认了我的答案:

如果您将 singletonInstance 声明为静态,就会发生这种情况。对于您的 Activity,singletonInstance 只是 SingletonClass 的一个实例。请记住,没有“静态实例”之类的东西,实例只是给定类的一个对象,使它成为静态的是您在范围内声明它的方式。对于 MyActivity,singletonInstance 不是静态的,即使在 SingletonClass 中您引用的是同一个对象/实例并且在那里它被声明为静态。

这样,GC 可以毫无问题地清理您的 Activity。我在 Android 上有一个类似的实现,它涉及一个服务,已经运行了数百个小时,没有任何内存或性能问题......

问候

于 2013-05-24T13:55:40.930 回答
1

我一直在使用 Square 的 LeakCanary 来检测我的 Android 应用程序中的内存泄漏,并且由于静态单例 obj 持有的引用,在我的一个 Activity 上检测到泄漏。

我的 Activity 与 Q 中的结构相同,其中 Activity 引用了单例 Presenter 类,但引用不是静态的。

public MyActivity extends Activity {
  private MyPresenter mPresenter;
  ...
  onCreate() {
     mPresenter = MyPresenter.getInstance()
     ...
  }
}
..
public class MyPresenter { // Different class
 private static MyPresenter mInstance;
... singleton code ...
}

我读了这个链接,我想这是有道理的。http://www.javaworld.com/article/2071737/core-java/plug-memory-leaks-in-enterprise-java-applications.html

一旦 Singleton 类被实例化,它就会在应用程序的生命周期内保留在内存中。其他对象也将具有对其的实时引用,因此永远不会被垃圾收集。

建议:- 避免从持久对象中引用对象。如果无法避免这种用法,请使用弱引用,这是一种不会阻止对象被垃圾回收的对象引用。

于 2015-12-21T19:25:05.673 回答