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
- MySQL
- Python
- Kuala Lumpur
- leadership
- program
- django
- programming_book
- comic agile
- hbase
- essay
- management
- hadoop
- Book
- web
- erlang
- agile
- ubuntu
- Linux
- Book review
- QT
- Artificial Intelligence
- Malaysia
- Software Engineering
- Java
- AI
- France
- Programming
- history
- RFID
- Italy
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));
List 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);
}
}
class 구조가 복잡해지면 정확도가 많이 떨어지기는 하지만 간단히 사용하기에 좋음
Comments