1

我不想提出一个模糊的问题,所以我会尽量让这个问题尽可能清楚(我会尽力而为)。

我知道垃圾收集长期以来一直是编程中的灰色地带。我不确定android或其他手机的情况。

我对 android 垃圾收集的了解:

  1. 它收集类系统类ojbects(由答案更正而成)。
  2. 编辑*“GC 仅在活动被销毁后收集活动项目。活动生命周期由清单中的属性驱动,也由启动它的意图标志驱动。” ——塞瓦·阿列克谢耶夫。正如评论者所说。
  3. 您可以使用“System.gc()”强制进行垃圾收集,但不建议这样做,因为它可能会删除一些重要的类项。

现在我从stackoverflow获得了这些信息(现在知道它不再是垃圾收集的灰色区域)

转到我的问题:

  1. 您如何获得有关垃圾收集的过程或一般信息(书籍、互联网文章等)的信息?
  2. 如果问题 1 没有答案,那么在开发需要持续使用内存的应用程序时,还应提醒开发人员的其他方式或方法是什么?
4

1 回答 1

2

我不确定你的信息是否正确。

它收集类系统类。

不会。它会收集无法从任何系统根目录访问的对象实例。系统根包括任何静态引用、来自线程的活动堆栈帧的任何引用、任何活动同步监视器以及本机代码段(全局或本地)持有的任何内容。如果从对象到根的路径向后跟踪参考图,则该对象被认为是活动的(因此无法回收)。任何没有根路径的对象都可以被垃圾收集器回收。类由 ClassLoader 引用,并且永远不会重新加载,因此不会被系统回收,除非收集了 ClassLoader 并且收集了这些类的所有实例。所以 Android 永远不会收集类系统类,因为 ClassLoader 永远不会被收集。

如果 android 清单文件指出活动是 hasNoHistory 或 singleTop,它“仅”从活动中收集项目

不,活动只不过是对象的一个​​实例。当对活动的引用消失时,它指向的所有引用都会消失,除非其他一些根指向该对象。通过设置 singleTop="true" 您只是告诉 Android 实例化此活动的单个实例,并且发送的所有意图都将由该单个实例处理。 它对 GC 没有任何影响。当一个活动失去它到根的路径时,无论该活动的设置是什么,它都会被回收。

您可以使用“System.gc()”强制进行垃圾收集,但不建议这样做,因为它可能会删除一些重要的类项。

无垃圾收集算法不会删除任何活动对象。根据您上面的定义,这意味着 GC 可以收集您正在使用的不正确的对象。如果是这样,那就是一个大错误。这也是垃圾收集算法的美妙之处,因为它们可以保证完美地清理垃圾。如果您的内存不足,程序员忘记删除引用,或者您对内存的使用不小心。您不应该调用 System.gc() 的原因是您/您的程序不知道何时是回收内存的最佳时间。垃圾收集器试图最大化(程序运行的时间)与(它花费在收集垃圾上的时间)的比率。它保留了非常详细的统计数据,并估计何时是运行垃圾收集的好时机,而不是简单地分配更多内存。

这就像打扫你的房子。你不能一直打扫,因为它会让做事花费更长的时间,有时你不得不让它变脏(比如做饭)。但是,如果您从不打扫房屋,则可能需要一整天的时间才能打扫干净。因此,在清理它比执行任务需要更长的时间之前,你必须在它变得多脏之间取得平衡。

这就是为什么你不应该在你的程序中计算/猜测/强制 GC 的原因,因为 Android 已经为你实现了它,并且会做得比你希望的更好。

这对开发人员意味着什么?

  1. 让 Android 处理 GC 应该运行的时间。
  2. 清理引用以帮助 GC 知道什么时候可以回收。对静态引用要非常小心,永远不要让静态引用对活动、服务等的引用。
  3. Don't allocate lots of small amounts of short lived memory. This will force more GC time to clean up. By allocating memory conservatively you are by definition helping that ratio.

Most of the time GC is very hands off. The only problems developers get into is not establishing boundaries for long living objects vs. UI objects. If a long living objects has a reference back to the UI that's a place you'll have to unregister or else you'll leak memory. It's ok for the UI to hold references to long living objects, but not the other way around.

The real issue with Android is how much you make the garbage collector work. If you keep the amount of memory you are using small then the garbage collector doesn't have big jobs it has to do. That doesn't mean you should reuse objects or create object pools, etc. But, you should be aware of what statements are creating memory, and how long those objects live for.

There are volumes of information on Garbage collection in general and particularly Java's Concurrent Mark and Sweep garbage collector. Android's garbage collector is not as performant, but it's pretty darn good. Most of the time I don't worry about GC unless there is a problem so it's mostly hands off.

And garbage collection isn't a grey area. It's very much well understood, and the industry has expanded the field quite a bit since Java was introduced in 1994.

于 2012-06-14T15:47:10.953 回答