分享
 
 
 

开源:对象运行时大小参考实现(sizeof)

王朝java/jsp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

支持递归引用,唯一不支持的就是不等长数组,不过要支持这个也不难,两个原因不改进它:

1.大部分数组都是等长的。

2.这个东西实在没看出有什么实际应用,这个是主要原因。

需要读者对反射和数组有比较深的认识:

package treeroot.util;

import java.lang.reflect.*;

import java.util.*;

/**

* Compute the size of a Runtime object or Primitive type.

* Because the memory allocation is unknown,we just add

* all the fields size of a object.

* the primitive size is thounght as

* boolean:1

* byte:1

* short:2

* char:2

* int:4

* float:4

* long:8

* double:8

* the array size are the sum of all the elements

* the null reference is thought to 4 byte.

* the Object instance has the size 8.

*

*/

public class Size

{

final private static int BOOLEAN=1;

final private static int BYTE=1;

final private static int SHORT=2;

final private static int CHAR=2;

final private static int INT=4;

final private static int FLOAT=4;

final private static int LONG=8;

final private static int DOUBLE=8;

final private static int REFERENCE=4;

final private static int OBJECT=8;

private static ThreadLocal objs=new ThreadLocal();

private static void init(Object o){

Map map=new IdentityHashMap();

map.put(o,null);

objs.set(map);

}

public static int sizeof(boolean i){

return BOOLEAN;

}

public static int sizeof(byte b){

return BYTE;

}

public static int sizeof(short s){

return SHORT;

}

public static int sizeof(char c){

return CHAR;

}

public static int sizeof(int i){

return INT;

}

public static int sizeof(float f){

return FLOAT;

}

public static int sizeof(long l){

return LONG;

}

public static int sizeof(double d){

return DOUBLE;

}

public static int sizeof(Object o){

init(o);

return sizeof0(o);

}

private static int sizeof0(Object o) {

int size=OBJECT;

//if the object is null

if(o==null) return REFERENCE;

Map map=(Map)objs.get();

Class c=o.getClass();

//if it is array

if(c.isArray()){

int[] dimension=getDimension(o);

int len=dimension.length;

Object obj=o;

int num=1;

for(int j=0;j<len-1;j++) num*=dimension[j];

if(dimension[len-1]==0){

size+=num*REFERENCE;

}

else{

num*=dimension[len-1];

//处理递归

int[] index;

Class type=c;

while(type.isArray()) type=type.getComponentType();

//基本类型的数组

if(type.isPrimitive()){

size+=num*sizeofPrimitive(type);

}

//引用类型数组

else{

for(int k=0;k<num;k++){

index=countToIndex(k,dimension);

Object temp=obj;

for(int m=0;m<len;m++){

temp=Array.get(temp,index[m]);

}

//加入数组中的所有对象

if(!map.containsKey(temp)){

size+=sizeof0(temp);

map.put(temp,null);

}

}

}

}

}

// all not-static fields

Field[] fs=getFields(o.getClass());

for(int i=0;i<fs.length;i++){

Field f=fs[i];

if(!Modifier.isStatic(f.getModifiers())){

Class type=f.getType();

//if it is primitive

if(type.isPrimitive()){

size+=sizeofPrimitive(type);

}

//recurtive

else{

Object obj=null;

try{

obj=f.get(o);

}

catch(IllegalAccessException e){

//won't be happen

throw new RuntimeException("impossible");

}

if(!map.containsKey(obj)){

size+=sizeof0(obj);

map.put(obj,null);

}

}

}

}

return size;

}

private static int[] countToIndex(int count,int[] d){

int[] res=new int[d.length];

int c=count;

int i=1;

while(c>0){

int t=1;

for(int j=i;j<d.length;j++) t*=d[j];

if(t>c) i++;

else{

res[i-1]=c/t;

c=c%t;

}

}

return res;

}

private static int sizeofPrimitive(Class c){

if (c==boolean.class){

return BOOLEAN;

}

else if(c==byte.class){

return BYTE;

}

else if(c==char.class){

return CHAR;

}

else if(c==short.class){

return SHORT;

}

else if(c==int.class){

return INT;

}

else if(c==float.class){

return FLOAT;

}

else if(c==long.class){

return LONG;

}

else if(c==double.class){

return DOUBLE;

}

else{

throw new IllegalArgumentException("Thrown by sizeOfPrimitive()");

}

}

private static int[] getDimension(Object obj){

int dimension=0;

Class c=obj.getClass();

while(c.isArray()){

dimension++;

c=c.getComponentType();

}

int[] res=new int[dimension];

Object o=obj;

for(int i=0;i<dimension-1;i++){

res[i]=Array.getLength(o);

o=Array.get(o,0);

}

res[dimension-1]=Array.getLength(o);

return res;

}

private static Field[] getFields(Class c){

Class superClass=c.getSuperclass();

Field[] s=null;

if(superClass!=null){

getFields(superClass);

}

Field[] fs=c.getDeclaredFields();

//设置为可访问的

Field.setAccessible(fs,true);

//合并

int size=0;

if(s!=null) size+=s.length;

if(fs!=null) size+=fs.length;

Field[] result=new Field[size];

int index=0;

if((s!=null)&&(s.length>0)){

System.arraycopy(s,0,result,0,s.length);

index+=s.length;

}

if((fs!=null)&&(fs.length>0)){

System.arraycopy(fs,0,result,index,fs.length);

}

return result;

}

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有