Java内存使用量测试 看看我们天天在用的JVM到底浪费了多少内存资源
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java内存使用量测试 看看我们天天在用的JVM到底浪费了多少内存资源相关的知识,希望对你有一定的参考价值。
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到底浪费了多少内存资源的主要内容,如果未能解决你的问题,请参考以下文章