0

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!

3
  • I don't see a problem with this... are you getting any exceptions? Is your array cleared unexpectedly? Commented May 19, 2011 at 11:45
  • I get an exception rarely on my side, but I can't say the same for the end users. The most predominant problem seems to be the array gets populated, the user wanders off to do something else outside my app, then comes back to it and some of the data in the array is no longer there. A value I just set could disappear 5-10 seconds later in some really weird cases. The GC is the only thing I can see that could be doing it and am trying to wrap my brain around it and reduce the memory overhead to stop it from happening (hopefully...). Commented May 19, 2011 at 20:50
  • Where is the array itself stored? Maybe in some kind of memory-sensitive cache? Commented May 19, 2011 at 21:11

3 Answers 3

1

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.

Sign up to request clarification or add additional context in comments.

2 Comments

The array is only populated once in the mainapp constructor. But I think I see where you're going with that, so I'll take a look. Thanks for the link! I may just go over to sqlLite to make life easier in terms of memory, though I have to rewrite a major portion to do it. Oh well, it'll more then likely be worth it in the end!
Dont just copy a database from assets. create a new one and just add the queries to populate. i have some nasty fragmentation experiences working with database copying from assets + you have double the space (its like having 2 same files on different locations in the file system). So i have to disagree with haphazard on this one. but as he also said 200 objects is not that much to hold into memory and the garbage collection isn't really an issue.
0

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.

2 Comments

Wouldn't that corrupt all the entries? If I create the UnitData object, add it to the list (which is a pointer to the object), then change the data in the object and add again (again the pointer), wouldn't both objects now contain the same data? Or does the system use a copy-constructor when adding it to the array?
no it wont. the object is added to the list so the previous object you created is getting collected by the garbage collector because there arent any references to it. this is why you are seeing a large garbage collection activity.
0

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 an OutOfMemoryError).

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)

1 Comment

All the data shown in that constructor is all that's in them. A few routines to get the data out and put data back in, but that's it. Not complex in any form. =/ The array is inside a class object thats created in the root/main android java class, so it's lifespan should be that of the entire app.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.