Android 垃圾收集器和 ArrayList
我在使用 Android 垃圾收集器时遇到问题,希望有人能指出我在这里可能做错了什么。我在程序开始时生成了大量数据并将其放入 ArrayList 中。下面是我正在做的事情的示例...
m_aUnitsPhysical.add(new UnitData("P01", 1, 0, 0, false, false, 300, UnitType.PHYSICAL, 1, "Unit Name"));
我的类构造函数中有大约 236 个这样的语句。数组定义为:
private ArrayList<UnitData> m_aUnitsPhysical; // Physical array listing
如果有帮助的话,类构造函数是...
public UnitData(String p_szID, int p_iAtk, int p_iDef, int p_iUp, boolean p_bLoot, boolean p_bHonor, int p_iCost, UnitType p_Type, int p_iLevel, String p_szName)
UnitData 是我的一个类,它只是存储数据,有点像旧的 C 结构。我知道在这个操作过程中我消耗了大量的内存。然而,当它完成时,垃圾收集器(如 logCat 中所示)将启动并释放大量数据。
那么,这是怎么回事?垃圾收集器是否对我执行上述语句的方式感到愤怒,或者它是否告诉我它正在清除其他应用程序的内存?有什么办法可以告诉吗?有没有更好的方法来完成我上面所做的事情,而不会使用这么多内存?我应该尝试使用 SqlLite 数据库而不是这样做吗?
我很少从用户那里收到他们遇到内存问题的报告,但它们确实正在发生。主要是当他们出于某种原因离开应用程序然后又返回时;数组中的数据消失。我只是想弄清楚我应该如何做,以防万一我做错了。任何见解将不胜感激!
I'm having a problem with the Android Garbage Collector and was hoping someone could point out what I may be doing wrong here. I have a lot of data at the start of my program that is generated and thrown into an ArrayList. Example of what I'm doing below...
m_aUnitsPhysical.add(new UnitData("P01", 1, 0, 0, false, false, 300, UnitType.PHYSICAL, 1, "Unit Name"));
There's about 236 of these statements in my class constructor. The array is defined as:
private ArrayList<UnitData> m_aUnitsPhysical; // Physical array listing
And in case it helps, the class constructor is...
public UnitData(String p_szID, int p_iAtk, int p_iDef, int p_iUp, boolean p_bLoot, boolean p_bHonor, int p_iCost, UnitType p_Type, int p_iLevel, String p_szName)
UnitData is a class of mine that simply stores the data, kinda like the old C struct. I know I'm chewing up huge amounts of memory during this operation. When it completes however, the Garbage Collector (as shown in logCat) kicks in and free's up huge amounts of data.
So, what's going on? Is the garbage collector angry with the way I'm doing the above statement, or is it telling me it's killing off memory from other applications? Is there any way to tell? Is there a better way of doing what I'm doing above that won't use so much memory? Should I try and use the SqlLite database instead of doing it this way?
I rarely get reports from my users that they've run into a memory issue, but they are occurring. Predominantly its when they leave the app for some reason or another then come back to it; the data in the array dissapears. I'm just trying to get a handle on how I should be doing this in case I'm doing it wrong. Any insight would be greatly appreciated!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果您要使用一组静态数据来交付应用程序(正如听起来的那样),那么您可能需要将数据集包含在预制数据库中。这是很棒的教程如何做到这一点。
也就是说,200 条记录不会导致任何内存问题。如果用户重新打开您的应用几次后出现问题,请确保您没有不必要地重新加载任何数据;在再次加载之前检查您的数组是否已填充。
If you are shipping the app with a static set of data (as it sounds you are) then you may want to include your data set in a pre-made database. Here is a great tutorial on how to do just that.
That said, 200 records should not cause any issues with memory. If the issue occurs after a user re-opens your app a few times, make sure that you aren't reloading any data unnecessarily; check to see if your array is populated already before loading it up again.
使用数据库存储大量数据。这是最好的、推荐的方法。
对于当前设置,尝试创建更少的对象。尝试使用单个对象,只需替换其数据并将其添加到列表中。不知道这是否会提高性能,但我相信它应该。建造者的成本很高。
Use a database for large amounts of data. that's the best and recomended way to go.
for the current setup try creating less objects. Try this with a single object and just replace its data and add it to a list.. Don't know if this will improve performance but i believe it should. constructors are costly.
GC将永远删除强引用的对象(即没有通过
WeakReference
等引用),即使它耗尽了内存(在这种情况下,它会抛出一个<代码>内存不足错误)。你的问题一定出在其他地方。
(其他发帖者建议使用数据库来存储您的值,但对于仅 200 个项目,我认为您的方法没有问题 - 除非这些对象非常复杂/巨大)
The GC will never delete strongly referenced objects (i.e. not referenced via
WeakReference
or the like), even if it runs out of memory (in that case, it will throw anOutOfMemoryError
).Your problem must be somewhere else.
(Other posters have recommended using a database to store your values, but for just 200 items, I see no problem with your approach -- unless these objects are extremely complex/huge)