1

I'm developing an Android-based 3D game in Java (not using the NDK). One of the must-haves for any game is a resource cache, in which I can store loaded textures, meshes, sounds, etc.

My plan is to develop a resource cache that hands out weak references to certain resources, so that only the cache itself keeps a strong reference to the resource, meaning that if I remove a resource from my cache, it will be garbage collected without me having to worry about it.

I'm having a hard time finding an answer to the following question though: Say I have filled my resource cache to the point where my heap space is almost completely full. I now want to load an additional resource, but its memory footprint is so large that it won't fit in my available heap space. To accommodate for the new object's size, I remove some entries from my cache and I load in the new object. Will this possibly cause an OutOfMemory exception? As long as the garbage collector hasn't sweeped through my recently removed objects, the memory stays in use, so is the garbage collector smart enough to run a new sweep in order to accommodate the newly allocated object?

ChrisV
  • 133
  • 2
  • 9
  • I don't know much about Android, but this mightn't be a good idea. Android already [special handles `Bitmap`s](https://developer.android.com/training/displaying-bitmaps/cache-bitmap.html) and I'd try to use it as much as possible (though I don't like it). – maaartinus Aug 11 '14 at 19:34

5 Answers5

2

The JVM will run a Full GC before throwing an OutOfMemoryError (it doesn't want to throw OOME, so it'll attempt everything possible). It's just that considerate.

Kayaman
  • 72,141
  • 5
  • 83
  • 121
2

GC is not guaranteed to run, although it usually does. I know I've seen OOME without GC and GC could have made a difference but it's rare. Usually if you've dereferenced objects and they are eligible for GC, then when you need memory allocated for new objects the JVM will do its job great and you will be fine. Properly dereferencing objects is usually the problem if you get an OOME and you think enough memory should be available.

See this post:

Is the garbage collector guaranteed to run before Out of Memory Error?

Also you can request GC, but that also does not guarantee that it will be run, and it may not be a good idea. See this post:

Garbage collector in Android

Community
  • 1
  • 1
Jim
  • 10,172
  • 1
  • 27
  • 36
1

The [Java Machine specification states(#6.3)] states this:

OutOfMemoryError: The Java Virtual Machine implementation has run out of either virtual
or physical memory, and the **automatic storage manager was unable to reclaim enough memory**
to satisfy an object creation request.

So JVM does guarantee that it will try what it can to free up memory through GC before it throws an OutOfMemoryError.

Abhishek
  • 422
  • 4
  • 13
0

To accommodate for the new object's size, I remove some entries from my cache and I load in the new object. Will this possibly cause an OutOfMemory exception? As long as the garbage collector hasn't sweeped through my recently removed objects, the memory stays in use, so is the garbage collector smart enough to run a new sweep in order to accommodate the newly allocated object?

By remove I understand you set them to null to make them eligible for GC. Although you have set them to null, the GC might decide not to do a memory sweep at all. Now you could explicitly call System.gc but then again the GC will be running in a separate low-priority thread. And collection of Objects will not be immediate. Now, once you try to load the large resource, the GC finds out that the memory is less, it starts its task to free as much memory as possible. But it will still throw OutOfMemory because you don't have memory when trying to load your resource.

TheLostMind
  • 35,966
  • 12
  • 68
  • 104
0

I just found out the answer to my own question in accordance with what Kayaman said earlier:

The Java Virtual Machine implementation has run out of either virtual or physical memory, and the automatic storage manager was unable to reclaim enough memory to satisfy an object creation request.

Found at http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.3

ChrisV
  • 133
  • 2
  • 9