如题所述
é¦å
ï¼æ们å
åä¸æ®µå¤§å®¶å¯è½ä¸æä¹åæè
认为ä¸å¯è½ç代ç ï¼ä¸ä¸ªç±»ä¸ï¼å 个类åé½æ¯privateç±»åï¼æ²¡æpublicæ¹æ³ï¼å¦ä½å¯¹è¿äºå±æ§è¿è¡è¯»åæä½ï¼çä¼¼ä¸å¯è½å¦ï¼ä¸ºä»ä¹ï¼è¿è¿èäºé¢å对象çå°è£
ï¼å
¶å®å¨å¿
è¦çæ¶åï¼çä¸éåé¨å¯ä»¥ä½¿å¾è¯è¨çç产åæ´å 强大ï¼å¯¹è±¡çåºååä¸ä¼å 为没æpublicæ¹æ³å°±æ æ³ä¿åæåå§ï¼OKï¼æ们ç®åå段代ç å¼ä¸ªå¤´ï¼éæ¥å¼å
¥å°æä¹æ ·å»æµè¯å¯¹è±¡ç大å°ï¼ä¸ä¸ä»£ç é常ç®åï¼ç¸ä¿¡ä¸ç¨æ解éä»ä¹ï¼
import java.lang.reflect.Field;
class NodeTest1 {
private int a = 13;
private int b = 21;
}
public class Test001 {
public static void main(String []args) {
NodeTest1 node = new NodeTest1();
Field []fields = NodeTest1.class.getDeclaredFields();
for(Field field : fields) {
field.setAccessible(true);
try {
int i = field.getInt(node);
field.setInt(node, i * 2);
System.out.println(field.getInt(node));
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
代ç æåºæ¬çææå°±æ¯ï¼å®ä¾åä¸ä¸ªNodeTest1è¿ä¸ªç±»çå®ä¾ï¼ç¶åååºä¸¤ä¸ªå±æ§ï¼åå«ä¹ä»¥2ï¼ç¶ååè¾åºï¼ç¸ä¿¡å¤§å®¶ä¼è®¤ä¸ºè¿æä¹å¯è½ï¼NodeTest1æ ¹æ¬æ²¡æpublicæ¹æ³ï¼ä»£ç å°±å¨è¿éï¼å°ä»£ç æ·è´åå»è¿è¡ä¸å°±OKäºï¼OKï¼ç°å¨ä¸è¯´è¿äºäºï¼è¿è¡ç»æ为ï¼
26
42
为ä»ä¹å¯ä»¥åå°ï¼æ¯æ¯ä¸ªå±æ§é½çäºä¸éé¨ï¼ä¸»è¦æ¯ä¸ºäºèªå·±æè å¤é¨æ¥å ¥çæ¹ä¾¿ï¼ç¸ä¿¡ç代ç èªå·±ä»ç»çæåï¼åºè¯¥ç¥éé¨å°±å¨ï¼field.setAccessible(true);代表è¿ä¸ªåç访é®è¢«æå¼ï¼å¥½æ¯æ¯ä¸éåé¨æå¼äºï¼åµåµï¼ä¸é¢çæ¹æ³å¦æä¸è®¾ç½®è¿ä¸ªï¼å°±ç´æ¥æ¥éã
çä¼¼å对象大å°æ²¡å¥å ³ç³»ï¼ä¸è¿è¿åªæ¯æç å¼çï¼å 为æ们é¦å è¦æ¿å°å¯¹è±¡çå±æ§ï¼æè½ç¥é对象ç大å°ï¼å¯¹è±¡å¦æ没ææä¾publicæ¹æ³æ们ä¹è¦ç¥éå®æåªäºå±æ§ï¼æ以æ们åé¢å¤åä¼ç¨å°è¿æ®µç±»ä¼¼ç代ç å¦ï¼
对象æµé大å°çæ¹æ³å ³é®ä¸ºjavaæä¾çï¼1.5è¿åææï¼ï¼java.lang.instrument.Instrumentationï¼å®æä¾äºä¸°å¯ç对ç»æççåæ¹é¢çè·è¸ªå对象大å°çæµéçAPIï¼æ¬æåªé述对象大å°çæµéæ¹æ³ï¼ï¼äºæ¯ä¹æå¿åäºï¼ä¸è¿æ¯è¾æ¶å¿çæ¯å®æ¯å®ä¾åç±»ï¼sun.instrument.IntrumentationImplæ¯sunå¼å¤´çï¼è¿ä¸ªé¬¼ä¸è¥¿æç¹ä¸å¥½æï¼ç¿»å¼æºç æé æ¹æ³æ¯privateç±»åï¼æ²¡æä»»ä½getInstanceçæ¹æ³ï¼åè¿ä¸ªç±»å¹²åï¼çæ¥è¿ä¸ªåªè½è¢«JVMèªå·±ç»åå§åäºï¼é£ä¹æä¹å°å®èªå·±åå§åçä¸è¥¿ååºæ¥ç¨å¢ï¼å¯ä¸è½æ³å°çå°±æ¯agent代çï¼é£ä¹æ们å æå¼ä»£çï¼é¦å æ¥åä¸ä¸ªç®åç对象æµéæ¹æ³ï¼
æ¥éª¤1ï¼ï¼å å建ä¸ä¸ªç¨äºæµè¯å¯¹è±¡å¤§å°çå¤çç±»ï¼
import java.lang.instrument.Instrumentation;
public class MySizeOf {
private static Instrumentation inst;
/**
*è¿ä¸ªæ¹æ³å¿ é¡»åï¼å¨agentè°ç¨æ¶ä¼è¢«å¯ç¨
*/
public static void premain(String agentArgs, Instrumentation instP) {
inst = instP;
}
/**
* ç´æ¥è®¡ç®å½å对象å ç¨ç©ºé´å¤§å°ï¼å æ¬ï¼å½åç±»åè¶ ç±»çåºæ¬ç±»åå®ä¾å段大å°
* å¼ç¨ç±»åå®ä¾å段å¼ç¨å¤§å°ãå®ä¾åºæ¬ç±»åæ°ç»æ»å ç¨ç©ºé´ãå®ä¾å¼ç¨ç±»åæ°ç»å¼ç¨æ¬èº«å ç¨ç©ºé´å¤§å°
* ä½æ¯ä¸å æ¬è¶ 类继æ¿ä¸æ¥çåå½å类声æçå®ä¾å¼ç¨å段ç对象æ¬èº«ç大å°ãå®ä¾å¼ç¨æ°ç»å¼ç¨ç对象æ¬èº«ç大å°
* ç¨æ¥æµéjava对象ç大å°ï¼è¿éå ç解è¿ä¸ªå¤§å°æ¯æ£ç¡®çï¼åé¢åæ·±åï¼
*/
public static long sizeOf(Object o) {
if(inst == null) {
throw new IllegalStateException("Can not access instrumentation environment.\n" +
"Please check if jar file containing SizeOfAgent class is \n" +
"specified in the java's \"-javaagent\" command line argument.");
}
return inst.getObjectSize(o);
}
}
æ¥éª¤2ï¼ä¸é¢æ们å好äºagentç代ç ï¼æ¤æ¶æ们è¦å°ä¸é¢è¿ä¸ªç±»ç¼è¯åæå 为ä¸ä¸ªjaræ件ï¼å¹¶ä¸å¨å ¶å å é¨çMETA-INF/MANIFEST.MFæ件ä¸å¢å ä¸è¡ï¼Premain-Class: MySizeOf代表æ§è¡ä»£ççå ¨åï¼è¿éçç±»å称æ¯æ²¡æpackageçï¼å¦æä½ æpackageï¼é£ä¹å°±åå ¨åï¼æ们è¿éå设æå å®çjarå å称为agent.jar(æå è¿ç¨è¿éç®åéè¿°ï¼å°±ä¸ç»è¯´äº)ï¼OKï¼ç»§ç»åä¸èµ°ï¼
æ¥éª¤3ï¼ç¼åæµè¯ç±»ï¼æµè¯ç±»ä¸åï¼
public class TestSize {
public static void main(String []args) {
System.out.println(MySizeOf.sizeOf(new Integer(1)));
System.out.println(MySizeOf.sizeOf(new String("a")));
System.out.println(MySizeOf.sizeOf(new char[1]));
}
}
ä¸ä¸æ¥åå¤è¿è¡ï¼è¿è¡åæ们åå¤åæ¥ä¼°ç®ä¸ç»ææ¯ä»ä¹ï¼ç®åææ¯å¨32bit模å¼ä¸è¿è¡jvmï¼æ³¨æï¼ä¸åä½æ°çJVMåæ°è®¾ç½®ä¸ä¸æ ·ï¼å¯¹è±¡å¤§å°ä¹ä¸ä¸æ ·å¤§ï¼ã
(1) é¦å çInteger对象ï¼å¨32bit模å¼ä¸ï¼classåºåå ç¨4byteï¼markåºåå ç¨æå°4byteï¼æ以æå°8byte头é¨ï¼Integerå é¨æä¸ä¸ªintç±»åçæ°æ®ï¼å 4个byteï¼æ以æ¤æ¶ä¸º8+4=12ï¼javaé»è®¤è¦æ±æç §8byteå¯¹è±¡å¯¹å ¶ï¼æä»¥å¯¹å ¶å°16byteï¼æ以æ们ç论ç»æ第ä¸ä¸ªåºè¯¥æ¯16ï¼
(2) åçStringï¼é¿åº¦ä¸º1ï¼String对象å é¨æ¬èº«æ4个ééæå±æ§ï¼éæå±æ§æ们ä¸è®¡ç®ç©ºé´ï¼å 为ææ对象é½æ¯å ±äº«ä¸å空é´çï¼ï¼4个ééæå±æ§ä¸ï¼æoffsetãcountãhash为intç±»åï¼åå«å ç¨4个byteï¼char value[]为ä¸ä¸ªæéï¼æéç大å°å¨bit模å¼ä¸æ64bitå¼å¯æéå缩ä¸é»è®¤ä¸º4byteï¼æ以å±æ§å ç¨äº16byteï¼Stringæ¬èº«æ8byte头é¨ï¼æ以å ç¨äº24byteï¼å ¶æ¬¡ï¼ä¸ä¸ªStringå å«äºå对象charæ°ç»ï¼æ°ç»å¯¹è±¡åæ®é对象çåºå«æ¯éè¦ç¨ä¸ä¸ªå段æ¥ä¿åæ°ç»çé¿åº¦ï¼æ以头é¨åæ12byteï¼javaä¸ä¸ä¸ªcharéç¨UTF-16ç¼ç ï¼å ç¨2个byteï¼æ以æ¯14byteï¼å¯¹å ¶å°16byteï¼24+16=40byteï¼
(3) 第ä¸ä¸ªå¨ç¬¬äºä¸ªåºç¡ä¸å·²ç»åæï¼å°±æ¯16byte大å°ï¼
ä¹å°±æ¯ç论ç»ææ¯ï¼16ã40ã16ï¼
æ¥éª¤4ï¼ç°å¨å¼å§è¿è¡ä»£ç ï¼è¿è¡ä»£ç åéè¦ä¿è¯classpathæåæçagent.jarå å«è¿å»ï¼
D:>javac TestSize.java
D:>java -javaagent:agent.jar TestSize
16
24
16
第ä¸ä¸ªå第ä¸ä¸ªç»æä¸è´äºï¼ä¸è¿å¥æªäºï¼ç¬¬äºä¸ªæä¹æ¯24ï¼ä¸æ¯40ï¼æä¹åç论ç»æåå·®è¿ä¹å¤§ï¼ååå°ç论ç»æä¸ï¼æä¸ä¸ª24æ¾ç»åºç°è¿ï¼24æ¯æStringèä¸å å«charæ°ç»ç空é´å¤§å°ï¼é£ä¹è¿ä¹ç®è¿çæ¯å¯¹çï¼å¯è§ï¼javaé»è®¤æä¾çæ¹æ³åªè½æµé对象å½åç大å°ï¼å¦æè¦æµéè¿ä¸ªå¯¹è±¡å®é ç大å°ï¼ä¹å°±æ¯å å«äºå对象ï¼é£ä¹å°±éè¦èªå·±åç®æ³æ¥è®¡ç®äºï¼æç®åçæ¹æ³å°±æ¯éå½ï¼ä¸è¿éå½ä¸é¡¹æ¯æä¸å欢ç¨çï¼æ æä¸å¨ä¸ä¸ªå°æ¹çå°æ人ç¨æ åäºä¸ä¸ªä»£ç åå¾è¿ä¸éï¼èªå·±ç¨å¾®æ¹äºä¸ï¼å°±æ¯ä¸é¢è¿ç§äºï¼ã
import java.lang.instrument.Instrumentation;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.Stack;
public class MySizeOf {
static Instrumentation inst;
public static void premain(String agentArgs, Instrumentation instP) {
inst = instP;
}
public static long sizeOf(Object o) {
if(inst == null) {
throw new IllegalStateException("Can not access instrumentation environment.\n" +
"Please check if jar file containing SizeOfAgent class is \n" +
"specified in the java's \"-javaagent\" command line argument.");
}
return inst.getObjectSize(o);
}
/**
* éå½è®¡ç®å½å对象å ç¨ç©ºé´æ»å¤§å°ï¼å æ¬å½åç±»åè¶ ç±»çå®ä¾å段大å°ä»¥åå®ä¾å段å¼ç¨å¯¹è±¡å¤§å°
*/
public static long fullSizeOf(Object obj) {//æ·±å ¥æ£ç´¢å¯¹è±¡ï¼å¹¶è®¡ç®å¤§å°
Map<Object, Object> visited = new IdentityHashMap<Object, Object>();
Stack<Object> stack = new Stack<Object>();
long result = internalSizeOf(obj, stack, visited);
while (!stack.isEmpty()) {//éè¿æ è¿è¡éå
result += internalSizeOf(stack.pop(), stack, visited);
}
visited.clear();
return result;
}
//å¤å®åªäºæ¯éè¦è·³è¿ç
private static boolean skipObject(Object obj, Map<Object, Object> visited) {
if (obj instanceof String) {
if (obj == ((String) obj).intern()) {
return true;
}
}
return (obj == null) || visited.containsKey(obj);
}
private static long internalSizeOf(Object obj, Stack<Object> stack, Map<Object, Object> visited) {
if (skipObject(obj, visited)) {//è·³è¿å¸¸éæ± å¯¹è±¡ãè·³è¿å·²ç»è®¿é®è¿ç对象
return 0;
}
visited.put(obj, null);//å°å½å对象æ¾å ¥æ ä¸
long result = 0;
result += sizeOf(obj);
Class <?>clazz = obj.getClass();
if (clazz.isArray()) {//å¦ææ°ç»
if(clazz.getName().length() != 2) {// skip primitive type array
int length = Array.getLength(obj);
for (int i = 0; i < length; i++) {
stack.add(Array.get(obj, i));
}
}
return result;
}
return getNodeSize(clazz , result , obj , stack);
}
//è¿ä¸ªæ¹æ³è·åéæ°ç»å¯¹è±¡èªèº«ç大å°ï¼å¹¶ä¸å¯ä»¥åç¶ç±»è¿è¡åä¸æç´¢
private static long getNodeSize(Class <?>clazz , long result , Object obj , Stack<Object> stack) {
while (clazz != null) {
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if (!Modifier.isStatic(field.getModifiers())) {//è¿éæå¼éæå±æ§
if (field.getType().isPrimitive()) {//è¿éæå¼åºæ¬å ³é®åï¼å 为åºæ¬å ³é®åå¨è°ç¨javaé»è®¤æä¾çæ¹æ³å°±å·²ç»è®¡ç®è¿äºï¼
continue;
}else {
field.setAccessible(true);
try {
Object objectToAdd = field.get(obj);
if (objectToAdd != null) {
stack.add(objectToAdd);//å°å¯¹è±¡æ¾å ¥æ ä¸ï¼ä¸éå¼¹åºå继ç»æ£ç´¢
}
} catch (IllegalAccessException ex) {
assert false;
}
}
}
}
clazz = clazz.getSuperclass();//æ¾ç¶ç±»classï¼ç´å°æ²¡æç¶ç±»
}
return result;
}
}
import java.lang.reflect.Field;
class NodeTest1 {
private int a = 13;
private int b = 21;
}
public class Test001 {
public static void main(String []args) {
NodeTest1 node = new NodeTest1();
Field []fields = NodeTest1.class.getDeclaredFields();
for(Field field : fields) {
field.setAccessible(true);
try {
int i = field.getInt(node);
field.setInt(node, i * 2);
System.out.println(field.getInt(node));
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
代ç æåºæ¬çææå°±æ¯ï¼å®ä¾åä¸ä¸ªNodeTest1è¿ä¸ªç±»çå®ä¾ï¼ç¶åååºä¸¤ä¸ªå±æ§ï¼åå«ä¹ä»¥2ï¼ç¶ååè¾åºï¼ç¸ä¿¡å¤§å®¶ä¼è®¤ä¸ºè¿æä¹å¯è½ï¼NodeTest1æ ¹æ¬æ²¡æpublicæ¹æ³ï¼ä»£ç å°±å¨è¿éï¼å°ä»£ç æ·è´åå»è¿è¡ä¸å°±OKäºï¼OKï¼ç°å¨ä¸è¯´è¿äºäºï¼è¿è¡ç»æ为ï¼
26
42
为ä»ä¹å¯ä»¥åå°ï¼æ¯æ¯ä¸ªå±æ§é½çäºä¸éé¨ï¼ä¸»è¦æ¯ä¸ºäºèªå·±æè å¤é¨æ¥å ¥çæ¹ä¾¿ï¼ç¸ä¿¡ç代ç èªå·±ä»ç»çæåï¼åºè¯¥ç¥éé¨å°±å¨ï¼field.setAccessible(true);代表è¿ä¸ªåç访é®è¢«æå¼ï¼å¥½æ¯æ¯ä¸éåé¨æå¼äºï¼åµåµï¼ä¸é¢çæ¹æ³å¦æä¸è®¾ç½®è¿ä¸ªï¼å°±ç´æ¥æ¥éã
çä¼¼å对象大å°æ²¡å¥å ³ç³»ï¼ä¸è¿è¿åªæ¯æç å¼çï¼å 为æ们é¦å è¦æ¿å°å¯¹è±¡çå±æ§ï¼æè½ç¥é对象ç大å°ï¼å¯¹è±¡å¦æ没ææä¾publicæ¹æ³æ们ä¹è¦ç¥éå®æåªäºå±æ§ï¼æ以æ们åé¢å¤åä¼ç¨å°è¿æ®µç±»ä¼¼ç代ç å¦ï¼
对象æµé大å°çæ¹æ³å ³é®ä¸ºjavaæä¾çï¼1.5è¿åææï¼ï¼java.lang.instrument.Instrumentationï¼å®æä¾äºä¸°å¯ç对ç»æççåæ¹é¢çè·è¸ªå对象大å°çæµéçAPIï¼æ¬æåªé述对象大å°çæµéæ¹æ³ï¼ï¼äºæ¯ä¹æå¿åäºï¼ä¸è¿æ¯è¾æ¶å¿çæ¯å®æ¯å®ä¾åç±»ï¼sun.instrument.IntrumentationImplæ¯sunå¼å¤´çï¼è¿ä¸ªé¬¼ä¸è¥¿æç¹ä¸å¥½æï¼ç¿»å¼æºç æé æ¹æ³æ¯privateç±»åï¼æ²¡æä»»ä½getInstanceçæ¹æ³ï¼åè¿ä¸ªç±»å¹²åï¼çæ¥è¿ä¸ªåªè½è¢«JVMèªå·±ç»åå§åäºï¼é£ä¹æä¹å°å®èªå·±åå§åçä¸è¥¿ååºæ¥ç¨å¢ï¼å¯ä¸è½æ³å°çå°±æ¯agent代çï¼é£ä¹æ们å æå¼ä»£çï¼é¦å æ¥åä¸ä¸ªç®åç对象æµéæ¹æ³ï¼
æ¥éª¤1ï¼ï¼å å建ä¸ä¸ªç¨äºæµè¯å¯¹è±¡å¤§å°çå¤çç±»ï¼
import java.lang.instrument.Instrumentation;
public class MySizeOf {
private static Instrumentation inst;
/**
*è¿ä¸ªæ¹æ³å¿ é¡»åï¼å¨agentè°ç¨æ¶ä¼è¢«å¯ç¨
*/
public static void premain(String agentArgs, Instrumentation instP) {
inst = instP;
}
/**
* ç´æ¥è®¡ç®å½å对象å ç¨ç©ºé´å¤§å°ï¼å æ¬ï¼å½åç±»åè¶ ç±»çåºæ¬ç±»åå®ä¾å段大å°
* å¼ç¨ç±»åå®ä¾å段å¼ç¨å¤§å°ãå®ä¾åºæ¬ç±»åæ°ç»æ»å ç¨ç©ºé´ãå®ä¾å¼ç¨ç±»åæ°ç»å¼ç¨æ¬èº«å ç¨ç©ºé´å¤§å°
* ä½æ¯ä¸å æ¬è¶ 类继æ¿ä¸æ¥çåå½å类声æçå®ä¾å¼ç¨å段ç对象æ¬èº«ç大å°ãå®ä¾å¼ç¨æ°ç»å¼ç¨ç对象æ¬èº«ç大å°
* ç¨æ¥æµéjava对象ç大å°ï¼è¿éå ç解è¿ä¸ªå¤§å°æ¯æ£ç¡®çï¼åé¢åæ·±åï¼
*/
public static long sizeOf(Object o) {
if(inst == null) {
throw new IllegalStateException("Can not access instrumentation environment.\n" +
"Please check if jar file containing SizeOfAgent class is \n" +
"specified in the java's \"-javaagent\" command line argument.");
}
return inst.getObjectSize(o);
}
}
æ¥éª¤2ï¼ä¸é¢æ们å好äºagentç代ç ï¼æ¤æ¶æ们è¦å°ä¸é¢è¿ä¸ªç±»ç¼è¯åæå 为ä¸ä¸ªjaræ件ï¼å¹¶ä¸å¨å ¶å å é¨çMETA-INF/MANIFEST.MFæ件ä¸å¢å ä¸è¡ï¼Premain-Class: MySizeOf代表æ§è¡ä»£ççå ¨åï¼è¿éçç±»å称æ¯æ²¡æpackageçï¼å¦æä½ æpackageï¼é£ä¹å°±åå ¨åï¼æ们è¿éå设æå å®çjarå å称为agent.jar(æå è¿ç¨è¿éç®åéè¿°ï¼å°±ä¸ç»è¯´äº)ï¼OKï¼ç»§ç»åä¸èµ°ï¼
æ¥éª¤3ï¼ç¼åæµè¯ç±»ï¼æµè¯ç±»ä¸åï¼
public class TestSize {
public static void main(String []args) {
System.out.println(MySizeOf.sizeOf(new Integer(1)));
System.out.println(MySizeOf.sizeOf(new String("a")));
System.out.println(MySizeOf.sizeOf(new char[1]));
}
}
ä¸ä¸æ¥åå¤è¿è¡ï¼è¿è¡åæ们åå¤åæ¥ä¼°ç®ä¸ç»ææ¯ä»ä¹ï¼ç®åææ¯å¨32bit模å¼ä¸è¿è¡jvmï¼æ³¨æï¼ä¸åä½æ°çJVMåæ°è®¾ç½®ä¸ä¸æ ·ï¼å¯¹è±¡å¤§å°ä¹ä¸ä¸æ ·å¤§ï¼ã
(1) é¦å çInteger对象ï¼å¨32bit模å¼ä¸ï¼classåºåå ç¨4byteï¼markåºåå ç¨æå°4byteï¼æ以æå°8byte头é¨ï¼Integerå é¨æä¸ä¸ªintç±»åçæ°æ®ï¼å 4个byteï¼æ以æ¤æ¶ä¸º8+4=12ï¼javaé»è®¤è¦æ±æç §8byteå¯¹è±¡å¯¹å ¶ï¼æä»¥å¯¹å ¶å°16byteï¼æ以æ们ç论ç»æ第ä¸ä¸ªåºè¯¥æ¯16ï¼
(2) åçStringï¼é¿åº¦ä¸º1ï¼String对象å é¨æ¬èº«æ4个ééæå±æ§ï¼éæå±æ§æ们ä¸è®¡ç®ç©ºé´ï¼å 为ææ对象é½æ¯å ±äº«ä¸å空é´çï¼ï¼4个ééæå±æ§ä¸ï¼æoffsetãcountãhash为intç±»åï¼åå«å ç¨4个byteï¼char value[]为ä¸ä¸ªæéï¼æéç大å°å¨bit模å¼ä¸æ64bitå¼å¯æéå缩ä¸é»è®¤ä¸º4byteï¼æ以å±æ§å ç¨äº16byteï¼Stringæ¬èº«æ8byte头é¨ï¼æ以å ç¨äº24byteï¼å ¶æ¬¡ï¼ä¸ä¸ªStringå å«äºå对象charæ°ç»ï¼æ°ç»å¯¹è±¡åæ®é对象çåºå«æ¯éè¦ç¨ä¸ä¸ªå段æ¥ä¿åæ°ç»çé¿åº¦ï¼æ以头é¨åæ12byteï¼javaä¸ä¸ä¸ªcharéç¨UTF-16ç¼ç ï¼å ç¨2个byteï¼æ以æ¯14byteï¼å¯¹å ¶å°16byteï¼24+16=40byteï¼
(3) 第ä¸ä¸ªå¨ç¬¬äºä¸ªåºç¡ä¸å·²ç»åæï¼å°±æ¯16byte大å°ï¼
ä¹å°±æ¯ç论ç»ææ¯ï¼16ã40ã16ï¼
æ¥éª¤4ï¼ç°å¨å¼å§è¿è¡ä»£ç ï¼è¿è¡ä»£ç åéè¦ä¿è¯classpathæåæçagent.jarå å«è¿å»ï¼
D:>javac TestSize.java
D:>java -javaagent:agent.jar TestSize
16
24
16
第ä¸ä¸ªå第ä¸ä¸ªç»æä¸è´äºï¼ä¸è¿å¥æªäºï¼ç¬¬äºä¸ªæä¹æ¯24ï¼ä¸æ¯40ï¼æä¹åç论ç»æåå·®è¿ä¹å¤§ï¼ååå°ç论ç»æä¸ï¼æä¸ä¸ª24æ¾ç»åºç°è¿ï¼24æ¯æStringèä¸å å«charæ°ç»ç空é´å¤§å°ï¼é£ä¹è¿ä¹ç®è¿çæ¯å¯¹çï¼å¯è§ï¼javaé»è®¤æä¾çæ¹æ³åªè½æµé对象å½åç大å°ï¼å¦æè¦æµéè¿ä¸ªå¯¹è±¡å®é ç大å°ï¼ä¹å°±æ¯å å«äºå对象ï¼é£ä¹å°±éè¦èªå·±åç®æ³æ¥è®¡ç®äºï¼æç®åçæ¹æ³å°±æ¯éå½ï¼ä¸è¿éå½ä¸é¡¹æ¯æä¸å欢ç¨çï¼æ æä¸å¨ä¸ä¸ªå°æ¹çå°æ人ç¨æ åäºä¸ä¸ªä»£ç åå¾è¿ä¸éï¼èªå·±ç¨å¾®æ¹äºä¸ï¼å°±æ¯ä¸é¢è¿ç§äºï¼ã
import java.lang.instrument.Instrumentation;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.Stack;
public class MySizeOf {
static Instrumentation inst;
public static void premain(String agentArgs, Instrumentation instP) {
inst = instP;
}
public static long sizeOf(Object o) {
if(inst == null) {
throw new IllegalStateException("Can not access instrumentation environment.\n" +
"Please check if jar file containing SizeOfAgent class is \n" +
"specified in the java's \"-javaagent\" command line argument.");
}
return inst.getObjectSize(o);
}
/**
* éå½è®¡ç®å½å对象å ç¨ç©ºé´æ»å¤§å°ï¼å æ¬å½åç±»åè¶ ç±»çå®ä¾å段大å°ä»¥åå®ä¾å段å¼ç¨å¯¹è±¡å¤§å°
*/
public static long fullSizeOf(Object obj) {//æ·±å ¥æ£ç´¢å¯¹è±¡ï¼å¹¶è®¡ç®å¤§å°
Map<Object, Object> visited = new IdentityHashMap<Object, Object>();
Stack<Object> stack = new Stack<Object>();
long result = internalSizeOf(obj, stack, visited);
while (!stack.isEmpty()) {//éè¿æ è¿è¡éå
result += internalSizeOf(stack.pop(), stack, visited);
}
visited.clear();
return result;
}
//å¤å®åªäºæ¯éè¦è·³è¿ç
private static boolean skipObject(Object obj, Map<Object, Object> visited) {
if (obj instanceof String) {
if (obj == ((String) obj).intern()) {
return true;
}
}
return (obj == null) || visited.containsKey(obj);
}
private static long internalSizeOf(Object obj, Stack<Object> stack, Map<Object, Object> visited) {
if (skipObject(obj, visited)) {//è·³è¿å¸¸éæ± å¯¹è±¡ãè·³è¿å·²ç»è®¿é®è¿ç对象
return 0;
}
visited.put(obj, null);//å°å½å对象æ¾å ¥æ ä¸
long result = 0;
result += sizeOf(obj);
Class <?>clazz = obj.getClass();
if (clazz.isArray()) {//å¦ææ°ç»
if(clazz.getName().length() != 2) {// skip primitive type array
int length = Array.getLength(obj);
for (int i = 0; i < length; i++) {
stack.add(Array.get(obj, i));
}
}
return result;
}
return getNodeSize(clazz , result , obj , stack);
}
//è¿ä¸ªæ¹æ³è·åéæ°ç»å¯¹è±¡èªèº«ç大å°ï¼å¹¶ä¸å¯ä»¥åç¶ç±»è¿è¡åä¸æç´¢
private static long getNodeSize(Class <?>clazz , long result , Object obj , Stack<Object> stack) {
while (clazz != null) {
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if (!Modifier.isStatic(field.getModifiers())) {//è¿éæå¼éæå±æ§
if (field.getType().isPrimitive()) {//è¿éæå¼åºæ¬å ³é®åï¼å 为åºæ¬å ³é®åå¨è°ç¨javaé»è®¤æä¾çæ¹æ³å°±å·²ç»è®¡ç®è¿äºï¼
continue;
}else {
field.setAccessible(true);
try {
Object objectToAdd = field.get(obj);
if (objectToAdd != null) {
stack.add(objectToAdd);//å°å¯¹è±¡æ¾å ¥æ ä¸ï¼ä¸éå¼¹åºå继ç»æ£ç´¢
}
} catch (IllegalAccessException ex) {
assert false;
}
}
}
}
clazz = clazz.getSuperclass();//æ¾ç¶ç±»classï¼ç´å°æ²¡æç¶ç±»
}
return result;
}
}
温馨提示:答案为网友推荐,仅供参考
第1个回答 2016-11-08
还不能恰当定义这个大小
~~~~~
~~~~~