Java世界中探寻sizeof

http://bbs.itheima.com/thread-17336-1-1.html 写道
在以前学习C或C++的时候,有一个函数sizeof可以求的一个数据项分配的字节数,为什么在java里面没有提供这样的函数?
那么我们如何知道一个数据分配项占用了多少个字节呢?难道每次不确定的时候都要翻文档查询吗?

 

http://bbs.itheima.com/thread-17336-1-1.html 写道
C中要使用sizeof主要是因为C程序员要自己管理堆内存的分配和释放,在使用malloc来获取堆内存时,我们必须知道要创建的对象的具体大小,才能根据对象的具体大小从堆中分配相应大小的动态内存,而获取对象大小这个工作就是通过sizeof来完成的。而java中的内存管理任务直接交给了JVM。因此,java中不存在类似sizeof的操作符。
如果楼主真的想实现sizeof功能,可以使用新提供的Instrument包。通过这个包提供的接口和类,我们可以很容易获取一个对象实际占用的内存大小。不过这个得jdk5.0以上。

java里面基本数据类型所占有的字节数都是一样的哈,与机器无关。
java中没有这样的功能计算占用字节数的,字节数都是固定的,查下表
byte b; 1字节 short s; 2字节
int i; 4字节 long l; 8字节
char c; 2字节(C语言中是1字节)
float f; 4字节 double d; 8字节
boolean bool; false/true

 

http://ar.newsmth.net/thread-5d4be64f02578b.html 写道
发信人: ThunderW (霹雳游侠), 信区: Java
标 题: Sizeof For Java(tm)
发信站: BBS 水木清华站 (Thu May 29 15:25:23 2003), 转信

http://www.glenmccl.com/tip_038.htm
今天没事看精华区,发现去年有人讨论java的sizeof。结论好想是没什么好办法。
上面的地址先讨论了一下java中没有sizeof的必要,然后给了一段实现sizeof的代码。

In previous issues we've mentioned that Java(tm) has no sizeof() operator
like C/C++. With uniform sizes for primitive data types, and a different
style of memory allocation, the need for sizeof() really isn't there. And
it's hard to define what sizeof() would mean anyway, given that an object
may not contain other objects, but only references to them.


But it's interesting to experiment with the 1.1 reflection feature and see
whether a method can be devised that will return useful information about
object sizes.


The Sizeof class below tries to do this, for a passed-in data structure.
It walks the structure and tallies up the total size in bytes. It ignores
alignment and packing issues and hidden fields in structures, and assumes
a boolean is of size 1 and a reference of size 4 (reference sizes may vary
; for example SZ_REF might be 8 on a machine with 64-bit pointers).


It does not count static data members of class instances, but does include
members inherited/implemented from superclasses and interfaces. It does
not follow references in object instances or in arrays, except for the case
of a multi-dimensional array, where the reference is to another array.


Included are some tests that illustrate what results are expected in given
cases.


import java.lang.reflect.*; 

class test_Class1 { 
private int a1; 
public byte a2; 
protected char a3[]; 
static byte a33; 
} 

class test_Class2 extends test_Class1 { 
static float a33; 
byte a3; 
short a4; 
double a5[] = new double[10]; 
} 

class test_Class3 extends test_Class2 { 
boolean a4; 
static int a44; 
char a5; 
long a6; 
} 

interface test_Class4 { 
public byte x = 1; 
} 

interface test_Class5 extends test_Class4 { 
public int x = 2; 
} 

class test_Class6 { 
public double x; 
} 

class test_Class7 extends test_Class6 implements test_Class5 { 
char x[] = null; 
} 

public class Sizeof { 

private static final int SZ_REF = 4; 

public static int sizeof(boolean b) 
{ 
return 1; 
} 

public static int sizeof(byte b) 
{ 
return 1; 
} 

public static int sizeof(char c) 
{ 
return 2; 
} 

public static int sizeof(short s) 
{ 
return 2; 
} 

public static int sizeof(int i) 
{ 
return 4; 
} 

public static int sizeof(long l) 
{ 
return 8; 
} 

public static int sizeof(float f) 
{ 
return 4; 
} 

public static int sizeof(double d) 
{ 
return 8; 
} 

private static int size_inst(Class c) 
{ 
Field flds[] = c.getDeclaredFields(); 
int sz = 0; 

for (int i = 0; i < flds.length; i++) { 
Field f = flds[i]; 
if (!c.isInterface() && 
(f.getModifiers() & Modifier.STATIC) != 0) 
continue; 
sz += size_prim(f.getType()); 
} 

if (c.getSuperclass() != null) 
sz += size_inst(c.getSuperclass()); 

Class cv[] = c.getInterfaces(); 
for (int i = 0; i < cv.length; i++) 
sz += size_inst(cv[i]); 

return sz; 
} 

private static int size_prim(Class t) 
{ 
if (t == Boolean.TYPE) 
return 1; 
else if (t == Byte.TYPE) 
return 1; 
else if (t == Character.TYPE) 
return 2; 
else if (t == Short.TYPE) 
return 2; 
else if (t == Integer.TYPE) 
return 4; 
else if (t == Long.TYPE) 
return 8; 
else if (t == Float.TYPE) 
return 4; 
else if (t == Double.TYPE) 
return 8; 
else if (t == Void.TYPE) 
return 0; 
else 
return SZ_REF; 
} 

private static int size_arr(Object obj, Class c) 
{ 
Class ct = c.getComponentType(); 
int len = Array.getLength(obj); 

if (ct.isPrimitive()) { 
return len * size_prim(ct); 
} 
else { 
int sz = 0; 
for (int i = 0; i < len; i++) { 
sz += SZ_REF; 
Object obj2 = Array.get(obj, i); 
if (obj2 == null) 
continue; 
Class c2 = obj2.getClass(); 
if (!c2.isArray()) 
continue; 
sz += size_arr(obj2, c2); 
} 
return sz; 
} 
} 

public static int sizeof(Object obj) 
{ 
if (obj == null) 
return 0; 

Class c = obj.getClass(); 

if (c.isArray()) 
return size_arr(obj, c); 
else 
return size_inst(c); 
} 

private static void err(String s) 
{ 
System.err.println("*** " + s + " ***"); 
} 

private static void test() 
{ 
if (sizeof(null) != 0) 
err("null"); 

if (sizeof(true) != 1) 
err("boolean"); 
if (sizeof((byte)37) != 1) 
err("byte"); 
if (sizeof('x') != 2) 
err("char"); 
if (sizeof((short)37) != 2) 
err("short"); 
if (sizeof(37) != 4) 
err("int"); 
if (sizeof(37L) != 8) 
err("long"); 
if (sizeof(37.0f) != 4) 
err("float"); 
if (sizeof(37.0) != 8) 
err("double"); 

if (sizeof(new boolean[0]) != 0) 
err("boolean[0]"); 
if (sizeof(new byte[10]) != 10) 
err("byte[10]"); 
if (sizeof(new char[10][10]) != 200 + 10 * SZ_REF) 
err("char[10][10]"); 
if (sizeof(new short[10][11][12]) != 2640 + 
120 * SZ_REF) 
err("short[10][11][12]"); 
if (sizeof(new int[0][10]) != 0) 
err("int[0][10]"); 

if (sizeof(new String[100]) != 100 * SZ_REF) 
err("String[100]"); 
if (sizeof(new String[10][10]) != 110 * SZ_REF) 
err("String[10][10]"); 

Object ov[] = new Object[3]; 
ov[0] = new byte[10]; 
ov[2] = new double[10]; 
if (sizeof(ov) != 90 + 3 * SZ_REF) 
err("Object[3]"); 

String sv[] = new String[10]; 
for (int i = 0; i < 10; i++) 
sv[i] = new String(); 
if (sizeof(sv) != 10 * SZ_REF) 
err("String[10]"); 

if (sizeof(new Object()) != 0) 
err("Object"); 
if (sizeof(new Integer(37)) != 4) 
err("Integer(37)"); 

if (sizeof(new test_Class1()) != 5 + SZ_REF) 
err("test_Class1"); 
if (sizeof(new test_Class2()) != 8 + 2 * SZ_REF) 
err("test_Class2"); 
if (sizeof(new test_Class3()) != 19 + 2 * SZ_REF) 
err("test_Class3"); 

if (sizeof(new test_Class7()) != 13 + SZ_REF) 
err("test_Class7"); 
} 

public static void main(String args[]) 
{ 
test(); 
} 

} 
 

-----
完。
--

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值