001package co.codewizards.cloudstore.core.util; 002 003import java.util.Map; 004import java.util.TreeMap; 005 006import org.slf4j.Logger; 007import org.slf4j.LoggerFactory; 008 009public final class DebugUtil { 010 011 private static final Logger logger = LoggerFactory.getLogger(DebugUtil.class); 012 013 private static final long KIB = 1024L; 014 private static final long MIB = KIB * 1024; 015 private static final long GIB = MIB * 1024; 016 private static final long TIB = GIB * 1024; 017 018 private DebugUtil() { 019 } 020 021 public static void logMemoryStats(Logger logger) { 022 if (logger == null) 023 logger = DebugUtil.logger; 024 025 if (! logger.isInfoEnabled()) 026 return; 027 028 final Runtime runtime = Runtime.getRuntime(); 029 030 runtime.gc(); 031 032 // max: limit of maximum allocatable memory allowed to the VM. Likely specified by -Xmx... 033 final long max = runtime.maxMemory(); 034 035 // allocated: memory currently allocated by the VM (requested from and granted by the OS). Might be less than 'max'. 036 final long allocated = runtime.totalMemory(); 037 038 // used: memory in use by Java objects (hence we invoke gc() above, otherwise this doesn't say anything useful). 039 final long used = allocated - runtime.freeMemory(); 040 041 // available: how much this JVM can still use for future objects -- with or without the need to allocate more from the OS. 042 final long available = max - used; 043 044 logger.info("logMemoryStats: max={}, allocated={}, used={}, available={}", 045 getHumanReadableSize(max), 046 getHumanReadableSize(allocated), 047 getHumanReadableSize(used), 048 getHumanReadableSize(available)); 049 } 050 051 private static String getHumanReadableSize(final long size) { 052 if (size >= TIB) 053 return String.format("%.1f TiB", (double) size / TIB); 054 055 if (size >= GIB) 056 return String.format("%.1f GiB", (double) size / GIB); 057 058 if (size >= MIB) 059 return String.format("%.1f MiB", (double) size / MIB); 060 061 if (size >= KIB) 062 return String.format("%.1f KiB", (double) size / KIB); 063 064 return String.format("%d B", size); 065 } 066 067 public static void logSystemProperties() { 068 if (! logger.isDebugEnabled()) { 069 return; 070 } 071 TreeMap<String, String> sortedSystemProperties = new TreeMap<>(); 072 for (Map.Entry<Object, Object> me : System.getProperties().entrySet()) { 073 String key = String.valueOf(me.getKey()); 074 String value = String.valueOf(me.getValue()); 075 sortedSystemProperties.put(key, value); 076 } 077 logger.debug(">>> System properties BEGIN >>>"); 078 for (Map.Entry<String, String> me : sortedSystemProperties.entrySet()) { 079 logger.debug(" * {} = {}", me.getKey(), me.getValue()); 080 } 081 logger.debug("<<< System properties END <<<"); 082 } 083}