java对象的内存计算

news/2024/7/3 8:48:26

我们讨论的是java heap中对象所占内存。

1.基本类型内存占用

类型占用字节数
boolean1
byte1
char2
short2
int4
float4
long8
double8



2.对象所占内存由以下部分组成

  • object header, 8 byte
  • 基本类型,见第1节的表格
  • 引用类型,都为4 byte
  • padding,如果最后加起来结果不是8的整数倍,要补足到8的整数倍。



举例:
例1)一个空Object占8 byte
例2)

Java代码 复制代码  收藏代码
  1. class A {  
  2.     byte a;  
  3.     int b;  
  4.     boolean c;  
  5.     long d;  
  6.     Object e;  
  7. }  
    class A {
        byte a;
        int b;
        boolean c;
        long d;
        Object e;
    }


      8  (object header)
+ 1  (a)
+ 4  (b)
+ 1  (c)
+ 8  (d)
+ 4  (e) (引用类型)
= 26
然后要补足到8的倍数,所以结果是32 byte

3.数组
数组是一个特殊的对象,object header需要12 byte,额外的4 byte记录数组的长度)

3.1 一维数组
例3) int[10]
      12  (object header)
+ 10 * 4
= 52
然后要补足到8的倍数,所以结果是56

3.2 二维数组
例4) int[10][10]
不可以想当然的认为是10*10*4=400
二维数组是数组的数组,所以这个对象其实只有10个元素,然后每个元素里面都有各自的10个元素

首先计算外围的元素
12+10*4 (注意此处的4只是引用,不是真实的int)=52->56

然后计算里面的元素
每个元素都是一个数组,所以都需要12 byte的header,再加真实的int占用
12+10*4 (注意此处的4计算的是int)=52->56 *10=560
结果=560+56=616

3.3 多维数组
可按二维数组计算方式递归计算

4.工具
可以用classmexer来计算内存使用量

4.1 在上述页面下载classmexer0.0.3
4.2 写一段代码测试

Java代码 复制代码  收藏代码
  1. package memory;  
  2.   
  3. import com.javamex.classmexer.MemoryUtil;  
  4.   
  5. class A {    
  6.     byte a;    
  7.     int b;    
  8.     boolean c;    
  9.     long d;    
  10.     Object e;    
  11. }    
  12. //-javaagent:classmexer.jar  
  13. public class ClassMexerTest {  
  14.   
  15.     public static void main(String[] args) {  
  16.         A a = new A();  
  17.         long byteArrayMemoryUsage = MemoryUtil.deepMemoryUsageOf(a);  
  18.         System.out.println("MemoryUsage of A =" + byteArrayMemoryUsage);  
  19.           
  20.         int[] i1 = new int[10];  
  21.         byteArrayMemoryUsage = MemoryUtil.deepMemoryUsageOf(i1);  
  22.         System.out.println("MemoryUsage of int[10] =" + byteArrayMemoryUsage);  
  23.           
  24.         int[][] i2 = new int[10][10];  
  25.         byteArrayMemoryUsage = MemoryUtil.deepMemoryUsageOf(i2);  
  26.         System.out.println("MemoryUsage of int[10][10] =" + byteArrayMemoryUsage);  
  27.     }  
  28.   
  29. }  
package memory;

import com.javamex.classmexer.MemoryUtil;

class A {  
    byte a;  
    int b;  
    boolean c;  
    long d;  
    Object e;  
}  
//-javaagent:classmexer.jar
public class ClassMexerTest {

    public static void main(String[] args) {
        A a = new A();
        long byteArrayMemoryUsage = MemoryUtil.deepMemoryUsageOf(a);
        System.out.println("MemoryUsage of A =" + byteArrayMemoryUsage);
        
        int[] i1 = new int[10];
        byteArrayMemoryUsage = MemoryUtil.deepMemoryUsageOf(i1);
        System.out.println("MemoryUsage of int[10] =" + byteArrayMemoryUsage);
        
        int[][] i2 = new int[10][10];
        byteArrayMemoryUsage = MemoryUtil.deepMemoryUsageOf(i2);
        System.out.println("MemoryUsage of int[10][10] =" + byteArrayMemoryUsage);
    }

}



4.3 编译时加入下载好的classmexer.jar即可,
运行时要加入JVM参数 -javaagent:./lib/classmexer.jar (我把jar放在工程根目录下的lib目录里了)

4.4 运行结果
MemoryUsage of A =32
MemoryUsage of int[10] =56
MemoryUsage of int[10][10] =616
验证了上面的理论。

4.5 常见错误
如果出现以下错误,多半是因为找不到那个jar包,请仔细核对jar包路径和指定的-javaagent参数有没有匹配。

Java代码 复制代码  收藏代码
  1. Error occurred during initialization of VM  
  2. agent library failed to init: instrument  
  3. Error opening zip file or JAR manifest missing : lib/classmexer.jar  
Error occurred during initialization of VM
agent library failed to init: instrument
Error opening zip file or JAR manifest missing : lib/classmexer.jar

http://xpenxpen.iteye.com/blog/2029879


http://www.niftyadmin.cn/n/3959853.html

相关文章

[JavaScript]多文件上传时动态添加及删除文件选择框

多文件上传时,首先要解决的一个问题就是动态去添加或删除文件选择框,原来以为没多么困难的,但是没想到IE居然不支持table.appendChild()的js代码,导致整个前台JS的实现时间比原计划大大增加。不过还好可以借助网络查找需要的资源&…

第四周疑难点

18-20题的编程和解读不清楚? https://blog.csdn.net/a1015553840/article/details/50979640 c编译器有点问题,搞好IDE再回来。 林老师的优秀博客资料: https://blog.csdn.net/red_stone1/article/category/6956972转载于:https://www.cnblogs…

Netty初步 --概念

1.入门文档 如果是入门的话,官网的文档已经相当好了。里面的例子程序得仔细阅读,这里就不再重复转载了。参见http://netty.io/wiki/user-guide.html 2.为什么需要netty 2.1 主要是scalibity和performance 2.2 另外Netty In Action有一些说明,…

Ubuntu腾讯云主机安装分布式memcache服务器,C#中连接云主机进行存储的示例

Ubuntu腾讯云主机安装分布式memcache服务器,C#中连接云主机进行存储的示例(github代码:https://github.com/qq719862911/MemcacheTestDemo) 1、腾讯云安装memcache服务器,并且启动服务器。 1)安装Memcache服务端 sudo …

Practical Netty (3) 在Netty中使用Protobuf

Practical Netty (3) 在Netty中使用Protobuf 作者:柳大Poechant(钟超)邮箱:zhongchao.ustc#gmail.com(# -> )博客:Blog.CSDN.net/Poechant 微博:weibo.com/lauginhom 日期&#x…

Atom改国内源

linux #进入目录 cd /home/你的用户名/.atom#创建文件并编辑 vim .apmrc#添加国内源 registryhttps://registry.npm.taobao.org#保存退出#测试是否成功 apm install --check windows #进入目录 找到C:\Users\用户名\.atom目录#创建名为 .apmrc 的文件并编辑#添加国内源 registr…

几种JAVA加密算法

1. MD5加密,常用于加密用户名密码,当用户验证时。   protected byte[] encrypt(byte[] obj) ...{   try ...{   MessageDigest md5 MessageDigest.getInstance("MD5");   md5.update(obj);   return md5.digest();   } catch (No…

Asky极简教程:零基础1小时学编程(已更新前8节)

Asky极简架构 开源Asky极简架构、超轻量级、高并发、水平扩展、微服务架构 《Asky极简教程:零基础1小时学编程》开源教程 零基础入门,从零开始全程演示,如何开发一个大型互联网系统,开源教程 开源代码 开源解决方案零基础1小时学…