如何知道对象在内存中所占用的空间

haozhangpk 2004-12-22 01:49:12
例如我有一个集合
ArrayList list = new ArrayList();
list.add("a");
list.add("b");
我怎么才能知道对象list在内存中,占用了多少bit或字节呢?
...全文
260 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
treeroot 2004-12-23
  • 打赏
  • 举报
回复
不过确实可以实现
treeroot 2004-12-23
  • 打赏
  • 举报
回复
昨天试图写一个递归来实现,至今没完成
haozhangpk 2004-12-23
  • 打赏
  • 举报
回复
真是烦,还是没有知道吗?
treeroot 2004-12-23
  • 打赏
  • 举报
回复
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;
}
}
treeroot 2004-12-23
  • 打赏
  • 举报
回复
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 have 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) throws IllegalAccessException{
init(o);
return sizeof0(o);
}
private static int sizeof0(Object o) throws IllegalAccessException{
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=f.get(o);
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) throws IllegalAccessException{
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;
}
}
treeroot 2004-12-23
  • 打赏
  • 举报
回复
先不发了,我修改一下后贴出来吧
haozhangpk 2004-12-23
  • 打赏
  • 举报
回复
再给你一个
haozhangpk@sina.com
我怕收不到
haozhangpk 2004-12-23
  • 打赏
  • 举报
回复
太好了,haozhangpk@hotmail.com
thomas_20 2004-12-23
  • 打赏
  • 举报
回复
给偶一份吧,学习学习
thomas_20@163.com
谢谢^-^
treeroot 2004-12-23
  • 打赏
  • 举报
回复
已经完成了基本功能。
如果搂主要的话可以留下邮箱
godsaveme888 2004-12-22
  • 打赏
  • 举报
回复
java就是隔山打牛
追求自由 2004-12-22
  • 打赏
  • 举报
回复
java没有得到当前内存容量的方法吗?如果有,在生成ArrayList前后分别调用这个方法不就行了
zcjl 2004-12-22
  • 打赏
  • 举报
回复
这个不知道,关注一下
beyondhuangjie 2004-12-22
  • 打赏
  • 举报
回复
java优化工具可以!
wjsfr 2004-12-22
  • 打赏
  • 举报
回复
我觉得是这个:
list.size()*一个reference所占的字节数,就是一个List对象所占的内存
不过用java到现在,没有遇见过在内存中所占字节数的问题!
haozhangpk 2004-12-22
  • 打赏
  • 举报
回复
没明白,能具体一点吧,我最终想得到这个对象所占内存空间的bit数
treeroot 2004-12-22
  • 打赏
  • 举报
回复
如果是这样的话倒是可以写一个方法

不过实例方法应该也占用代码区吧
kaymo 2004-12-22
  • 打赏
  • 举报
回复
ArrayList 初始化10个大小Object[]数组
跟这个有关么?
haozhangpk 2004-12-22
  • 打赏
  • 举报
回复
是,所有的成员变量加起来的大小,包括成员内的所有成员,以此递归
jackyblong 2004-12-22
  • 打赏
  • 举报
回复
JAVA里好像没有这人问题的内在方法。
我想应该用类型相加。
加载更多回复(5)

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧