I have a java application that uses extensively the memory. It keeps a data-structure that grows very fast and is the responsible for the biggest amount of memory used.
In order to avoid an Out Of Memory, I decide to flush the data-structure to a repository (file or db) and post process it.
The problem that I face consists of choosing the time(when the used memory is "close" to reach the maximum allowed) to flush the data-structure into the repository. One way would be to keep track of the data-structure's memory usage on every update.
dataStructure.onUpdate(new CheckMemoryIfReachedMax() {
public void onUpdate(long usedMemory) {
if (usedMemory == MaxMemory) {
datastucture.flushInRepository();
}
}
}
The main problem in this case is that isnt easy to change the data-structure to keep track of the memory.
Another possible solution would be to get the used memory from the JVM and compare it to the maximum memory.
Runtime runtime = Runtime.getRuntime();
long freeMemory = runtime.freeMemory();
if (freeMemory < MaxUsedMemory) {
datastucture.flushInRepository();
}
In this case the problem is that the memory usage just gives a hint of how much memory is used, being that we cannot predict the moment the Garbage Collector removes the objects. This solution would make me flush more often the data-structure to the repository, so the application performance might suffer from this.
Is there any general pattern used in those cases? Do you have any suggestion about which of the solution would be better suited to the problem?