2

Is there a reliable approach to empty the cache before the memory is full? Or even better limit the cache according to current available "actual" free memory (hard-referenced objects)?

A soft referenced cache is not a good idea due to high GC penalty, once hit the limit all cache entries need to be reloaded.

Also the value runtime.freeMemory() is not that reliable for my purpose because even if it is too low, after the next GC cycle there might be plenty of free space so it's not a good indication of the actual used memory.

I tried to figure out how much memory each primitive time would consume so I would know the actual memory usage of the cache and put a limit on it, but couldn't find a reliable way to figure out how much memory would be used to store a String reference of size n.

2
  • 3
    There isn't a reliable metric based on the length() of a String as different strings can share the same backing char[] - "This is a very long string".substring(5,2) is the string is but it holds a reference to the "very long" char[]. Commented Jan 7, 2013 at 9:52
  • 1
    Answers here might be able to give an idea. stackoverflow.com/questions/13855013/… Commented Jan 7, 2013 at 9:54

3 Answers 3

2

Have two or three collections. If you want degrading service with memory availability you can have.

  • a map on the most recent entries, e.g. LinkedHashMap.
  • a map of soft references.
  • a map of weak references.

You can control how large each map should be with the knowledge that weak references can be cleared after a minor collection, soft references will be cleared if needed, and the strong references map has the core data which will always be retained.

BTW: If you are hitting your memory limit often, you should consider buying more memory up to about 32 GB per JVM. You can buy 32 GB for less than $200.

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

3 Comments

How would this make a difference? How do I make sure the cache will not cause OutOfMemmoryError? My application is running on GAE cloud server so adding more memory is not that cheap.
The difference is; You can have a small number entries cached as a minimum and you will not get an OOME unless this small number is still too much i.e. your application was about to die anyway. It is a shame the cloud providers haven't keep up with newer technologies. My 8 year old has 8 GB in his PC as it cost me £24 and buying 4 GB didn't make much sense.
The best way to avoid OOME is to reduce you memory consumption. To do that you need to memory profile your application with VisualVM or ideally a commercial profiler.
2

Try one of the more recent Oracle 1.7 incarnations. They should offer a GarbageCollectorMXBean and GarbageCollectionNotificationInfo. Use that to monitor the amount of used/unused memory after each GC cycle. There is some sample code here. You can then use a multi-level cache as suggested by Peter to clean out the outer level when memory is tight, but retain the smaller first-level cache.

1 Comment

Unfortunately I want it to be GAE compatible which does not support Java 1.7, but seems like that's the way to go in the future if querying the managed bean is fast enough.
1

I would suggest that the simplest solution would be to change your references to weak references. This way the references can still finalized and garbage collected when all strong references have gone out of scope.

See: http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/ref/WeakReference.html

1 Comment

As I mentioned in my question the problem with soft/weak references is that they will be all wiped out once the memory is short at any time making all the cache become empty, and it would be very expensive to rebuild the whole map. I want it to be smarted just empty enough of the cache to free up some space or just keep the size of the map bellow that threshold.

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.