Very late after the original post, I know, but I thought I'd post an example of how I did it. Hope this will be useful to someone (I emphasize this is a proof of a prime example, nothing more ... not particularly elegant :))
Just insert these two functions into the class and it should work.
EDIT: Oh and import java.util.ArrayList; import java.util.List; import java.util.ArrayList; import java.util.List;
public static int MEM(){ return (int)(Runtime.getRuntime().maxMemory()-Runtime.getRuntime().totalMemory() +Runtime.getRuntime().freeMemory())/1024/1024; } public static void main(String[] args) throws InterruptedException { List list = new ArrayList(); //get available memory before filling list int initMem = MEM(); int lowMemWarning = (int) (initMem * 0.2); int highMem = (int) (initMem *0.8); int iteration =0; while(true) { //use up some memory list.add(Math.random()); //report if(++iteration%10000==0) { System.out.printf("Available Memory: %dMb \tListSize: %d\n", MEM(),list.size()); //if low on memory, clear list and await garbage collection before continuing if(MEM()<lowMemWarning) { System.out.printf("Warning! Low memory (%dMb remaining). Clearing list and cleaning up.\n",MEM()); //clear list list = new ArrayList(); //obviously, here is a good place to put your warning logic //ensure garbage collection occurs before continuing to re-add to list, to avoid immediately entering this block again while(MEM()<highMem) { System.out.printf("Awaiting gc...(%dMb remaining)\n",MEM()); //give it a nudge Runtime.getRuntime().gc(); Thread.sleep(250); } System.out.printf("gc successful! Continuing to fill list (%dMb remaining). List size: %d\n",MEM(),list.size()); Thread.sleep(3000); //just to view output } } } }
EDIT. However, this approach still relies on judicious memory tuning in jvm using -Xmx.
EDIT2: It seems that the gc query string really helps with this, at least on my jvm. YMMV.
miklatov
source share