1. 程式人生 > >Java內存使用量測試 看看我們天天在用的JVM到底浪費了多少內存資源

Java內存使用量測試 看看我們天天在用的JVM到底浪費了多少內存資源

數據 static ini apm long setlength into set等 dom

JVM內存使用量測試
測試各種不同的數據結構在JVM中的內存使用量

  1 import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
  2 
  3 import java.lang.management.ManagementFactory;
  4 import java.lang.management.MemoryMXBean;
  5 import java.lang.management.MemoryUsage;
  6 import java.util.HashSet;
  7 import java.util.Map;
  8 import
java.util.Set; 9 10 /** JVM內存使用量測試 11 * 測試各種不同的數據結構在JVM中的內存使用量 12 */ 13 public class MemUsageTest 14 { 15 static final long KILO = 1024L; 16 static final long MEGA = KILO * KILO; 17 18 static double divide(long a, long b) { 19 return ((double)a)/b; 20 } 21 static
StringBuilder sbMem = new StringBuilder(16); 22 static String memStr(long mem) { 23 return memStr(mem, null); 24 } 25 static String memStr(long mem, String msg) { 26 sbMem.setLength(0); 27 if(msg==null || msg.length()==0){ 28 29 }else{
30 sbMem.append(msg).append(": "); 31 } 32 33 if(mem == 0){ 34 sbMem.append("0"); 35 return sbMem.toString(); 36 } 37 38 if(mem < 0){ 39 sbMem.append("- "); 40 mem = -mem; 41 } 42 if(mem >= MEGA){ 43 sbMem.append(mem / MEGA); 44 sbMem.append("M "); 45 mem %= MEGA; 46 } 47 if(mem >= KILO){ 48 sbMem.append(mem / KILO); 49 sbMem.append("K "); 50 mem %= KILO; 51 } 52 if(mem > 0){ 53 sbMem.append(mem); 54 sbMem.append("B"); 55 } 56 return sbMem.toString(); 57 } 58 59 static final Runtime RUNTIME = Runtime.getRuntime(); 60 static final MemoryMXBean MEM_MXBEAN = ManagementFactory.getMemoryMXBean(); 61 static long LAST_MEM = 0; 62 public static void printMemUsage() { 63 printMemUsage(null); 64 } 65 public static void printMemUsage(String msg) { 66 if(msg==null || msg.length()==0){ 67 System.out.println("==================== MemUsage ===================="); 68 }else{ 69 System.out.println("==================== MemUsage ("+msg+") ===================="); 70 } 71 System.gc(); 72 73 /*System.out.println(divide(RUNTIME.totalMemory()-RUNTIME.freeMemory(), MEGA));//usage.getUsed() 74 System.out.println(divide(RUNTIME.totalMemory(), MEGA));//usage.getCommitted() 75 */ //System.out.println(divide(RUNTIME.maxMemory(), MEGA));//usage.getMax() 76 77 MemoryUsage usage = MEM_MXBEAN.getHeapMemoryUsage(); 78 //usage = MEM_MXBEAN.getNonHeapMemoryUsage(); 79 //System.out.println(memStr(usage.getInit())); 80 System.out.println(memStr(usage.getUsed(), "使用量 "));//使用量 81 System.out.println(memStr(usage.getUsed()-LAST_MEM, "使用量增量"));//使用量增量 82 System.out.println(memStr(usage.getCommitted(), "提交總量 "));//提交總量 83 //System.out.println(memStr(usage.getMax())); 84 85 //if(LAST_MEM <= 0){ 86 LAST_MEM = usage.getUsed(); 87 //} 88 } 89 90 public static int same(int i){ 91 return i; 92 } 93 public static Object same(Object i){ 94 return i; 95 } 96 97 static String[] strs; 98 static Object[] objs; 99 static int[] ints; 100 static Integer[] integers; 101 static Set<Integer> integerSet; 102 public static void main( String[] args ) 103 { 104 printMemUsage(); 105 106 //String[] 107 //每個對象平均占用60B 108 strs = new String[(int) MEGA]; 109 printMemUsage("String[]"); 110 111 int i; 112 for(i=0;i<strs.length;i++){ 113 //strs[i] = ""; 114 //strs[i] = new String(""); 115 strs[i] = String.format("%08d", i); 116 //strs[i] = String.valueOf(Math.random()); 117 } 118 printMemUsage(); 119 120 strs = null; 121 printMemUsage(); 122 123 //Object[] 124 //每個對象平均占用20B 125 objs = new Object[(int) MEGA]; 126 printMemUsage("Object[]"); 127 128 for(i=0;i<objs.length;i++){ 129 objs[i] = new Object(); 130 } 131 printMemUsage(); 132 133 objs = null; 134 printMemUsage(); 135 136 //int[] 137 //每個對象平均占用4B 138 ints = new int[(int) MEGA]; 139 printMemUsage("int[]"); 140 141 for(i=0;i<ints.length;i++){ 142 ints[i] = same(i); 143 } 144 printMemUsage(); 145 146 ints = null; 147 printMemUsage(); 148 149 //Integer[] 150 //每個對象平均占用20B 151 integers = new Integer[(int) MEGA]; 152 printMemUsage("Integer[]"); 153 154 for(i=0;i<integers.length;i++){ 155 integers[i] = i; 156 } 157 printMemUsage(); 158 159 integers = null; 160 printMemUsage(); 161 162 //HashSet<Integer> 163 //每個對象平均占用56B 164 integerSet = new HashSet<Integer>(1000000); 165 printMemUsage("HashSet<Integer>"); 166 167 for(i=0;i<MEGA;i++){ 168 integerSet.add(i); 169 } 170 printMemUsage(); 171 172 integerSet = null; 173 printMemUsage(); 174 175 //fastutil.IntOpenHashSet 176 //每個對象平均占用8B 177 integerSet = new IntOpenHashSet(1000000); 178 printMemUsage("fastutil.IntOpenHashSet"); 179 180 for(i=0;i<MEGA;i++){ 181 ((IntOpenHashSet)integerSet).add(i); 182 } 183 printMemUsage(); 184 185 integerSet = null; 186 printMemUsage(); 187 } 188 }

運行結果如下,由此可見JVM對String、Object、封裝類型(如Integer)等的存儲均有較大的消耗。

使用fastutil的集合類,可以比Java系統集合類節省不少的內存空間,因為HashMap、HashSet等類不僅不支持直接存放原始類型int,而且還要把存儲的對象封裝成Node(哈希桶鏈表的節點),這裏消耗的內存空間比fastutil多出了7倍之多!

==================== MemUsage ====================
使用量       : 1M 187K 384B
使用量增量: 1M 187K 384B
提交總量   : 123M 
==================== MemUsage (String[]) ====================
使用量       : 4M 546K 128B
使用量增量: 3M 358K 768B
提交總量   : 123M 
==================== MemUsage ====================
使用量       : 60M 730K 728B
使用量增量: 56M 184K 600B
提交總量   : 622M 512K 
==================== MemUsage ====================
使用量       : 730K 712B
使用量增量: - 60M 16B
提交總量   : 632M 512K 
==================== MemUsage (Object[]) ====================
使用量       : 4M 730K 728B
使用量增量: 4M 16B
提交總量   : 606M 
==================== MemUsage ====================
使用量       : 20M 730K 728B
使用量增量: 16M 
提交總量   : 631M 
==================== MemUsage ====================
使用量       : 730K 712B
使用量增量: - 20M 16B
提交總量   : 631M 512K 
==================== MemUsage (int[]) ====================
使用量       : 4M 730K 728B
使用量增量: 4M 16B
提交總量   : 629M 512K 
==================== MemUsage ====================
使用量       : 4M 730K 728B
使用量增量: 0
提交總量   : 602M 
==================== MemUsage ====================
使用量       : 730K 712B
使用量增量: - 4M 16B
提交總量   : 629M 
==================== MemUsage (Integer[]) ====================
使用量       : 4M 730K 728B
使用量增量: 4M 16B
提交總量   : 606M 
==================== MemUsage ====================
使用量       : 20M 728K 728B
使用量增量: 15M 1022K 
提交總量   : 625M 512K 
==================== MemUsage ====================
使用量       : 730K 712B
使用量增量: - 19M 1022K 16B
提交總量   : 627M 512K 
==================== MemUsage (HashSet<Integer>) ====================
使用量       : 730K 952B
使用量增量: 240B
提交總量   : 627M 512K 
==================== MemUsage ====================
使用量       : 56M 729K 368B
使用量增量: 55M 1022K 440B
提交總量   : 628M 
==================== MemUsage ====================
使用量       : 731K 288B
使用量增量: - 55M 1022K 80B
提交總量   : 642M 
==================== MemUsage (fastutil.IntOpenHashSet) ====================
使用量       : 8M 795K 288B
使用量增量: 8M 64K 
提交總量   : 610M 
==================== MemUsage ====================
使用量       : 8M 751K 152B
使用量增量: - 44K 136B
提交總量   : 638M 
==================== MemUsage ====================
使用量       : 751K 88B
使用量增量: - 8M 64B
提交總量   : 602M 

Java內存使用量測試 看看我們天天在用的JVM到底浪費了多少內存資源