在Android活动的静态变量中存储(大)hashmap安全吗?

在Android活动的静态变量中存储(大)hashmap安全吗?,android,andengine,Android,Andengine,几个月来,我一直在用AndEngine框架测试我的技能,为Android开发游戏。 现在我面临着一个令人困惑的问题,在我们的项目中,我们将活动的所有TextureAtlas(即纹理)保存在该活动的静态HashMap中。这会产生一些内存泄漏问题或类似的不愉快的事情吗?我在安卓系统中听到了很多关于静态变量的矛盾的事情,所以我不知道该怎么想 请注意,屏幕旋转被阻止,因此至少少了一个陷阱 提前谢谢 这会产生一些内存泄漏问题或类似的不愉快的事情吗 根据定义,Java中的静态数据成员是内存泄漏。这些对象以及

几个月来,我一直在用AndEngine框架测试我的技能,为Android开发游戏。
现在我面临着一个令人困惑的问题,在我们的项目中,我们将活动的所有TextureAtlas(即纹理)保存在该活动的静态HashMap中。这会产生一些内存泄漏问题或类似的不愉快的事情吗?我在安卓系统中听到了很多关于静态变量的矛盾的事情,所以我不知道该怎么想

请注意,屏幕旋转被阻止,因此至少少了一个陷阱

提前谢谢

这会产生一些内存泄漏问题或类似的不愉快的事情吗

根据定义,Java中的静态数据成员是内存泄漏。这些对象以及它们引用的任何对象都不能被垃圾收集,至少在移除对它们的静态引用之前是如此

这是否是一个问题是另一回事。例如,泄漏一个四字节整数不会成为问题。您可以使用DDMS生成堆转储,并使用MAT对其进行检查,以查看
TextureAtlas的静态
HashMap
的“for realz”内存量

对于像
HashMap
这样的静态集合,关键是确保删除不再需要的条目。当集合不断增长时,内存泄漏会成为一个问题,因为您不断向集合中添加内容,而从不删除任何内容。根据您的情况,一个
WeakHashMap
(其中密钥被弱持有,当没有其他任何东西使用您的密钥时,允许地图条目消失)可能是一个更好的解决方案

这会产生一些内存泄漏问题或类似的不愉快的事情吗

根据定义,Java中的静态数据成员是内存泄漏。这些对象以及它们引用的任何对象都不能被垃圾收集,至少在移除对它们的静态引用之前是如此

这是否是一个问题是另一回事。例如,泄漏一个四字节整数不会成为问题。您可以使用DDMS生成堆转储,并使用MAT对其进行检查,以查看
TextureAtlas的静态
HashMap
的“for realz”内存量


对于像
HashMap
这样的静态集合,关键是确保删除不再需要的条目。当集合不断增长时,内存泄漏会成为一个问题,因为您不断向集合中添加内容,而从不删除任何内容。根据您的情况,一个
WeakHashMap
(其中键被弱持有,当没有其他东西在使用您的键时,允许映射条目消失)可能是一个更好的解决方案。

当有对活动实例的反向引用时,静态变量是不好的。因为在应用程序的使用生命周期中(例如,当您切换手机时),活动会多次重新创建

例如,以下代码是安全的:

private static Long mMyLong;
但这个不安全:

private static Context mContext;
有时要小心,有一些不明显的背景参考

为了避免这种麻烦,您应该将静态HashMap存储在应用程序类中(您可以在这里找到我关于应用程序类创建的另一篇文章)。因此,无论您的活动生命周期如何,您的hashmap都将创建一次。此外,你的表现也会有所提高。为了确保不保留任何引用,可以在YourActivity.ondestory()中将hashmap及其内容设置为null,然后在YourActivity.onCreate()中重新创建它


如果hashmap保留任何死亡引用,您可以使以下体验成为sur。如上所述,将hashmap放在应用程序类中。将手机翻转至纵向/横向以重新创建您的活动。因此,如果您的活动因使用hashmap对象而崩溃,这意味着它会保留对您的活动的引用。

当存在对活动实例的反向引用时,静态变量是错误的。因为在应用程序的使用生命周期中(例如,当您切换手机时),活动会多次重新创建

例如,以下代码是安全的:

private static Long mMyLong;
但这个不安全:

private static Context mContext;
有时要小心,有一些不明显的背景参考

为了避免这种麻烦,您应该将静态HashMap存储在应用程序类中(您可以在这里找到我关于应用程序类创建的另一篇文章)。因此,无论您的活动生命周期如何,您的hashmap都将创建一次。此外,你的表现也会有所提高。为了确保不保留任何引用,可以在YourActivity.ondestory()中将hashmap及其内容设置为null,然后在YourActivity.onCreate()中重新创建它


如果hashmap保留任何死亡引用,您可以使以下体验成为sur。如上所述,将hashmap放在应用程序类中。将手机翻转至纵向/横向以重新创建您的活动。因此,如果您的活动因使用hashmap对象而崩溃,这意味着它会保留对您的活动的引用。

事实上,我知道在横向和纵向之间切换时会重新创建上下文,但我不确定这是否会导致TextureAtlas出现同样的问题。该类没有对上下文的引用。答案是thx所以你的问题应该是:“TextureAtlas是否引用了上下文?”我个人不知道,请在ANdroid的源代码中查看它。好吧,我是在询问上下文,但对于任何可能导致类似问题的其他类都是如此。除了上下文之外,我不知道还有什么。因此我的问题…我在上面的主要帖子中添加了一个新段落。有趣的建议。谢谢你澄清你的观点。我将对此进行测试。这个解决方案的唯一限制是,如果我在地图中放置了很多大的对象,那么地图可能达到的大小。虽然如果我在activity onDestroy中清理它,我会没事的。事实上,我知道在横向和纵向之间切换时会重新创建上下文,但我不确定