几个月来,我一直在测试我使用 AndEngine 框架开发 Android 游戏的技能。
现在我面临一个令人困惑的问题,在我们的项目中,我们将一个活动的所有TextureAtlas(即纹理)保存在该活动中的静态HashMap中。这会产生一些内存泄漏问题或类似的不愉快的事情吗?我在 Android 中听说过很多关于静态变量的矛盾的东西,所以我不知道该怎么想。
请注意,屏幕旋转被阻止,因此它至少少了一个陷阱。
提前致谢 !
这会产生一些内存泄漏问题或类似的不愉快的事情吗?
根据定义,Java 中的静态数据成员是内存泄漏。这些对象,以及它们引用的任何东西,都不能被垃圾回收,至少在对它们的静态引用被删除之前是这样。
这是否是一个问题是另一回事。例如,泄漏一个四字节整数不会成为问题。HashMap
您可以使用 DDMS 生成堆转储并使用 MAT 检查它,以查看“for realz”您的静态内存有多少TextureAtlas
。
对于像 a 这样的静态集合HashMap
,关键是确保您正在删除不再需要的条目。当集合不断增长时,内存泄漏成为一个问题,因为你不断地向它们添加东西,而永远不会删除任何东西。根据您的情况,a WeakHashMap
(键被弱持有,允许地图条目在没有其他人使用您的键时消失)可能是一个更好的解决方案。
当有对 Activity 实例的反向引用时,静态变量是不好的。因为活动在应用程序的使用生命周期中多次重新创建(例如,当您切换手机时)。
例如,以下代码是安全的:
private static Long mMyLong;
但是这个不安全:
private static Context mContext;
有时要小心,有一些不明显的反向引用。
为了避免这种麻烦,您应该将静态 HashMap 存储在您的应用程序类中(您可以在这里找到我关于应用程序类创建的另一篇文章https://stackoverflow.com/a/13994622/1789730)。因此,无论您的活动生命周期如何,您的哈希图都将创建一次。此外,您将获得性能。为了不保留任何引用,您可以在 YourActivity.onDestroy() 中将 hashmap 及其内容设置为 null,然后在 YourActivity.onCreate() 中重新创建它。
如果 hashmap 保留任何死亡引用,您可以做出以下体验。如上所述,将 hashmap 放在应用程序类中。将手机翻转为纵向/横向以重新创建您的活动。因此,如果您的活动因使用 hashmap 对象而崩溃,这意味着它会保留对您活动的引用。