2023年12月6日发(作者:)

JAVA使用SizeOf

JAVA使用SizeOf

研究一下JAVA的SizeOf

引用外部类实现JAVA的SizeOf

JAVA本身是没有SizeOf的,因此我们需要去MavenRepository中下载JAR包(也可以使用maven等),因为这里只是做一个简单测试,就直接

下载了JAR包。

点击jar下载,最新的版本也是2015年,算是比较老了。

下载成功后导入自己的JAVA项目,具体怎么导入网上有很多教程,就不赘述了。

可以看到我这里已经引用成功了,import后可以直接使用这些类了。

简单的测试

接下来来做一些简单的测试,看看这个类提供的sizeOf方法是否准确。

n((newObject()));

在控制台我们可以看到输出的结果是16。

可能还有人不清楚为什么会是16,这边给出一个链接,可以学习一下,个人觉得还是挺有帮助的。

Object存储内容

Integer等也都可以测试一下,结果还是很正确的。

那比较重要的就是数组和对象中再包含对象的,能否还是比较精确呢?

我们先来写一个简单的对象。

先给出一些例子,大家想想是为什么。

geEstimator;

public class SizeOfTest{

public static void main(String[] args){ n((newMemTest()));

}

}

class MemTest{Integer a =12;}

结果是32,其实挺好解释的,MemTest本身和Object对象一样,占用12字节,a这个引用在指针压缩后占用4字节,加上a的16,自然是32。

我们把Integer改成int,结果答案还是16。

再加上一个int b,就变成了24。这是因为指针对齐。

如果你刚才有仔细去研究那个链接的话,你会看到Object本来应该占12个字节的,只是为了对齐变成了16。加上一个int的4字节,刚好是16。

但我们改成Integer a;发现结果也是16。难道a不应该是8个字节的地址的引用吗?可以去了解一下指针压缩,默认是开启的,因此占用四个字

节。

这样就可以解释的通了,再多做几次测试,加上各种各样的对象,也是这样的,符合我们计算出来的值。

再测试一种比较有意思的情况:

这种情况显示的是40。

这种情况却是56。

这是因为Java在处理Integer时使用了一个缓存,其中缓存了-128到127之间的数字对应的Integer对象。

看来源码应该不是简单的相加。(还没来得及研究源码)

对研究JAVA内存结构很有帮助。

研究数组的情况

其实一维数组的情况不难,一维数组就相当于一个对象头+一片数组数据空间。

这里要注意:数组的对象头是这样的,MarkWord占用8字节,Class Point占用4字节,Length 数组占用4字节。

比如int[1]就是8+4+4+4,再对齐,就是24,测试发现相符。

那二维数组呢,我们先理论分析一下,以int[2][2]为例,先从二维的角度来看,对象头应该是16个字节,两个一维的指针一共8字节,两个一维数

组各自如上占用24字节。也就是16+8+48=72字节,验证一下,果不其然。

总结

对这个SizeOf的测试就到此为止啦,主要是精确度的测试,结合网上查到的资料,精确度应该还行。

JAVA的内存实在太复杂了,方法区,栈内存,特别是常量池又分为了好几种。。。了解的不够透彻,陷入了好几次圈圈中,查了好多资料才了

解,因此决定也发个简书回馈一下。

之后准备测试一下比较复杂的情况下的精确度和效率。