Reputation: 61
I am exploring a tree of stuff in Java, but I am memory limited. I handle this by looking at occupancy stats, and when I'm over 80% (say) stop allocating new bits of the tree to avoid the OutOfMemory. And just compute using what I've got so far using the 20% headroom.
Then every now and again I decide to move down the tree. This should free up 90% of the tree I've allocated because I forget the old root and move to one of it's children. And it does free that memory, but only if I call System.gc(), which is evil and stops my world. But if I don't call gc() my limiting code stops me adding to my tree.
What I want to do is call out to the G1 or CMS collectors that I could really do with the old generation getting a clean, and carrying on computing and allocate new bits of the tree as the collector does it's job.
Any ideas how that can be accomplished? Or, equally helpful, how I could avoid this artificial 80% limit, that is the root of my problem.
Upvotes: 3
Views: 400
Reputation: 43052
Setting -XX:+ExplicitGCInvokesConcurrent
should trigger a concurrent cycle if you invoke System.gc()
Alternatively you could use -XX:CMSInitiatingOccupancyFraction=50 -XX:+UseCMSInitiatingOccupancyOnly
for CMS which will initiate concurrent cycles once the heap reaches that threshold, since you're aiming for 80%+ occupancy that would basically continuously burn CPU time (possibly limited by GCTimeRatio
, i'm not sure how those goals interact) to clean the old generation and thus free up memory swiftly.
The equivalent parameter for G1GC (InitiatingHeapOccupancyPercent
) already defaults to 45%, so it should already be running mixed collection cycles if you have reached that point. You should inspect GC logs to verify.
Or, equally helpful, how I could avoid this artificial 80% limit, that is the root of my problem.
Upvotes: 1