/** forces all soft references to be cleared by trying to allocate an enormous chunk of memory, * returns a description of what was done * (tune with {@link #forceClearSoftReferences(long, int)} * for greater than 200M precision in the output message, if you really care about that) */ public static String forceClearSoftReferences() { return forceClearSoftReferences(1000*1000, Integer.MAX_VALUE); } /** as {@link #forceClearSoftReferences()} but gives control over headroom and max chunk size.
protected void forceGc() { MemoryUsageTracker.forceClearSoftReferences(); System.gc(); System.gc(); }
/** force a round of Brooklyn garbage collection */ public void gcIteration() { try { logUsage("brooklyn gc (before)"); gcTasks(); logUsage("brooklyn gc (after)"); double memUsage = 1.0 - 1.0*Runtime.getRuntime().freeMemory() / Runtime.getRuntime().maxMemory(); if (memUsage > brooklynProperties.getConfig(FORCE_CLEAR_SOFT_REFERENCES_ON_MEMORY_USAGE_LEVEL)) { LOG.info("Forcing brooklyn gc including soft-reference cleansing due to memory usage: "+getUsageString()); MemoryUsageTracker.forceClearSoftReferences(); System.gc(); System.gc(); LOG.info("Forced cleansing brooklyn gc, usage now: "+getUsageString()); } else if (brooklynProperties.getConfig(DO_SYSTEM_GC)) { // Can be very useful when tracking down OOMEs etc, where a lot of tasks are executing // Empirically observed that (on OS X jvm at least) calling twice blocks - logs a significant // amount of memory having been released, as though a full-gc had been run. But this is highly // dependent on the JVM implementation. System.gc(); System.gc(); logUsage("brooklyn gc (after system gc)"); } } catch (Throwable t) { Exceptions.propagateIfFatal(t); LOG.warn("Error during management-context GC: "+t, t); } }
String clearanceResult = MemoryUsageTracker.forceClearSoftReferences(100*1000, 10*1000*1000); LOG.info("Forcing memory eviction: " + clearanceResult);