blob: 15e474e48f47e64a1e634aa3045e8f0400d846b8 [file] [log] [blame]
package org.unicode.cldr.util;
import java.text.CharacterIterator;
import java.text.StringCharacterIterator;
public class MemoryHelper {
/**
* Get the amount of memory still available for us to allocate,
* including not only freeMemory but also maxMemory - totalMemory
*
* https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Runtime.html#freeMemory()
*
* Generally: freeMemory <= totalMemory <= maxMemory
*
* @param callerId a string identifying the caller, used in log if verbose
* @param verbose if true, log the stats
* @return the available memory, in bytes
*/
public static synchronized long availableMemory(String callerId, boolean verbose) {
final Runtime r = Runtime.getRuntime();
long freeMem = r.freeMemory();
long maxMem = r.maxMemory();
long totalMem = r.totalMemory();
if (freeMem > totalMem || totalMem > maxMem) {
log(callerId, "Values returned by Runtime violate assumptions!");
verbose = true;
}
long availMem = freeMem + maxMem - totalMem;
if (verbose) {
log(callerId, "Available memory: " + humanReadableByteCountSI(availMem) +
"; free: " + humanReadableByteCountSI(freeMem) +
"; max: " + humanReadableByteCountSI(maxMem) +
"; total: " + humanReadableByteCountSI(totalMem));
}
return availMem;
}
private static void log(String callerId, String message) {
System.out.println("MemoryHelper[" + callerId + "]: " + message);
}
/**
* Convert a byte count to a human readable string
* Use SI (1 k = 1,000), not Binary (1 K = 1,024)
*
* @param bytes the number such as 1234567890
* @return the formatted string such as "1.2 GB"
*
* Source: https://programming.guide/java/formatting-byte-size-to-human-readable-format.html
*/
public static String humanReadableByteCountSI(long bytes) {
if (-1000 < bytes && bytes < 1000) {
return bytes + " B";
}
CharacterIterator ci = new StringCharacterIterator("kMGTPE");
while (bytes <= -999_950 || bytes >= 999_950) {
bytes /= 1000;
ci.next();
}
return String.format("%.1f %cB", bytes / 1000.0, ci.current());
}
}