Java对象内存空间大小计算-创新互联
八股文中很明确的告诉你了基础类型的大小 ,如下图:
创新互联公司是一家从事企业网站建设、网站设计、成都网站设计、行业门户网站建设、网页设计制作的专业网络公司,拥有经验丰富的网站建设工程师和网页设计人员,具备各种规模与类型网站建设的实力,在网站建设领域树立了自己独特的设计风格。自公司成立以来曾独立设计制作的站点上千。类型 | 值大小(byte) | 对象内存大小(byte) | 备注 |
---|---|---|---|
byte | 1 | 16 | |
char | 2 | 16 | |
int | 4 | 16 | |
float | 4 | 16 | |
long | 8 | 24 | |
double | 16 | 24 |
很明显基础类型值的大小和内存大小不一致,所以计算也不能混淆,这里我们着重弄懂对象大小怎么去计算;
环境 Win10系统64位,JDK8(1.6版本之后默认开启了指针压缩)
方式1:
我们用jdk debug包的工具jdk.nashorn.internal.ir.debug.ObjectSizeCalculator去获取Java对象大小
方式2:
用三方工具包
org.openjdk.jol jol-core0.13
这里我们用方式1实验:
int, float等基础都类型都是以对象的方式存在于内存中,且空对象大小为16byte,看看对象的结构,因HotSpot JVM规范要求对象起始地址必须是8字节的整数倍,所以空对象为16byte
二、分析String字符串对象内存大小明白了这个之后我们再来探究一下字符串的内存空间大小
举例 String s ="hello";
我们发现空字符串占40byte, 而"hello"占56byte, char[] 占32byte
我们利用jol-core工具包里面的 ClassLayout.parseInstance(“**”).toPrintable() 看看结构
char[]的对象结构 对象头16byte+10byte(hello)+ 对齐填充6byte = 32byte
String="hello" 12byte对象头+4byte数组指针+4byte hash值+对齐填充4byte =24byte + 32byte数组值 = 56byte
所以空字符串 有24byte基础+16byte char[] = 40byte
三、BitSet内存大小计算除了常见的字符串很好计算大小,但是在选择k-v存储还是bitset存储通常需要做一下大小计算,这个问题在redis中很常见,我们先用Java做计算
1亿个用户签到问题,例如id区间[100000000,200000000]
选择K-V方式 :
1亿个K用Integer对象存入 10^9*16byte/1024/1024 >1500MB ,还不算Value的空间
选择BitSet,BitSet空对象 48byte,但是内部是由一个可扩展的long[]维护比特位转化而成的整数
1-63放入word[0],64-127放入word[1],....... 依次类推达到2*10^9的时候大概是32MB,假设你只有少量的数存贮而且maxId很大,那么依然会有这么大的空间占用,而K-V方式则占用较少,由于用户ID 10^9以下的都没有用过所以可以将ID偏移减去10^9个数,这样的话 maxId = 2*10^9-10^9 = 10^9 存储空间减少一半为16MB,Redis中的BitMap结构和Java中的BitSet功能差不多,但是BitMap占用空间更少
bitset空间大小速查表
大ID | byte | MB |
---|---|---|
1000 | 168 | |
10000(万) | 2088 | 0.001 |
100000(十万) | 16424 | 0.015 |
500000 (五十万) | 65576 | 0.06 |
1000000 (一百万) | 131112 | 0.125 |
5000000 (五百万) | 1048616 | 1 |
10000000(一千万) | 2097192 | 2 |
50000000(五千万) | 8388648 | 8 |
100000000(亿) | 16777256 | 16 |
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
新闻名称:Java对象内存空间大小计算-创新互联
网页链接:http://pwwzsj.com/article/iedgs.html