Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- Italy
- comic agile
- web
- MySQL
- Python
- Kuala Lumpur
- program
- hbase
- Programming
- France
- agile
- erlang
- hadoop
- RFID
- Book review
- Book
- Spain
- leadership
- Java
- Software Engineering
- programming_book
- QT
- history
- essay
- management
- Malaysia
- Linux
- ubuntu
- psychology
- django
Archives
- Today
- Total
MemoryCounter 본문
// http://www.javaspecialists.eu/archive/Issue078.html import java.lang.reflect.*; import java.util.*; /** * This class can estimate how much memory an Object uses. It is * fairly accurate for JDK 1.4.2. It is based on the newsletter #29. */ public final class MemoryCounter { private static final MemorySizes sizes = new MemorySizes(); private final Map visited = new IdentityHashMap(); private final Stack stack = new Stack(); public synchronized long estimate(Object obj) { assert visited.isEmpty(); assert stack.isEmpty(); long result = _estimate(obj); while (!stack.isEmpty()) { result += _estimate(stack.pop()); } visited.clear(); return result; } private boolean skipObject(Object obj) { if (obj instanceof String) { // this will not cause a memory leak since // unused interned Strings will be thrown away if (obj == ((String) obj).intern()) { return true; } } return (obj == null) || visited.containsKey(obj); } private long _estimate(Object obj) { if (skipObject(obj)) return 0; visited.put(obj, null); long result = 0; Class clazz = obj.getClass(); if (clazz.isArray()) { return _estimateArray(obj); } while (clazz != null) { Field[] fields = clazz.getDeclaredFields(); for (int i = 0; i < fields.length; i++) { if (!Modifier.isStatic(fields[i].getModifiers())) { if (fields[i].getType().isPrimitive()) { result += sizes.getPrimitiveFieldSize( fields[i].getType()); } else { result += sizes.getPointerSize(); fields[i].setAccessible(true); try { Object toBeDone = fields[i].get(obj); if (toBeDone != null) { stack.add(toBeDone); } } catch (IllegalAccessException ex) { assert false; } } } } clazz = clazz.getSuperclass(); } result += sizes.getClassSize(); return roundUpToNearestEightBytes(result); } private long roundUpToNearestEightBytes(long result) { if ((result % 8) != 0) { result += 8 - (result % 8); } return result; } protected long _estimateArray(Object obj) { long result = 16; int length = Array.getLength(obj); if (length != 0) { Class arrayElementClazz = obj.getClass().getComponentType(); if (arrayElementClazz.isPrimitive()) { result += length * sizes.getPrimitiveArrayElementSize(arrayElementClazz); } else { for (int i = 0; i < length; i++) { result += sizes.getPointerSize() + _estimate(Array.get(obj, i)); } } } return result; } } import java.util.*; public class MemorySizes { private final Map primitiveSizes = new IdentityHashMap() { { put(boolean.class, new Integer(1)); put(byte.class, new Integer(1)); put(char.class, new Integer(2)); put(short.class, new Integer(2)); put(int.class, new Integer(4)); put(float.class, new Integer(4)); put(double.class, new Integer(8)); put(long.class, new Integer(8)); } }; public int getPrimitiveFieldSize(Class clazz) { return ((Integer) primitiveSizes.get(clazz)).intValue(); } public int getPrimitiveArrayElementSize(Class clazz) { return getPrimitiveFieldSize(clazz); } public int getPointerSize() { return 4; } public int getClassSize() { return 8; } } import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.HashMap; public class TestMemoryUsage { private static final long MEGABYTE = 1024L * 1024L; public static long bytesToMegabytes(long bytes) { return bytes / MEGABYTE; } public static void main(String[] args) { final int SIZE = 10000; int[][] intArray = new int[SIZE][SIZE]; for ( int i = 0; i < SIZE; ++i ) for ( int j = 0; j < SIZE; ++j ) intArray[i][j] = i * j; System.out.println("counted memory size =\t" + 4 * SIZE * SIZE); System.out.println("estimated memory size =\t" + new MemoryCounter().estimate(intArray)); long[][] longArray = new long[SIZE][SIZE]; for ( int i = 0; i < SIZE; ++i ) for ( int j = 0; j < SIZE; ++j ) longArray[i][j] = i * j; System.out.println("counted memory size =\t" + 8 * SIZE * SIZE); System.out.println("estimated memory size =\t" + new MemoryCounter().estimate(longArray)); Listclass 구조가 복잡해지면 정확도가 많이 떨어지기는 하지만 간단히 사용하기에 좋음intList = new ArrayList (SIZE); for ( int i = 0; i < SIZE; ++i ) intList.add(i); System.out.println("estimated int list memory size =\t" + new MemoryCounter().estimate(intList)); List longList = new ArrayList (SIZE); for ( int i = 0; i < SIZE; ++i ) longList.add((long)i); System.out.println("estimated long list memory size =\t" + new MemoryCounter().estimate(longList)); Map map = new HashMap (); for ( int i = 0; i < SIZE; ++i ) map.put(i, new String("value " + i)); System.out.println("estimated hash map memory size =\t" + new MemoryCounter().estimate(map)); long estSize = 0; for ( int i = 0; i < map.size(); ++i ) { estSize += new MemoryCounter().estimate(new Integer(i)) + new MemoryCounter().estimate(new String("value " + i)); } System.out.println("estimated hash map memory size =\t" + estSize); } }
Comments