`
xpenxpen
  • 浏览: 711131 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

java对象的内存计算

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

1.基本类型内存占用
类型占用字节数
boolean 1
byte 1
char 2
short 2
int 4
float 4
long 8
double 8


2.对象所占内存由以下部分组成
  • object header, 8 byte
  • 基本类型,见第1节的表格
  • 引用类型,都为4 byte
  • padding,如果最后加起来结果不是8的整数倍,要补足到8的整数倍。


举例:
例1)一个空Object占8 byte
例2)
    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 写一段代码测试
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参数有没有匹配。
Error occurred during initialization of VM
agent library failed to init: instrument
Error opening zip file or JAR manifest missing : lib/classmexer.jar
分享到:
评论

相关推荐

    JAVA对象所占内存大小计算例子

    首先,我们需要理解Java对象内存占用的基本原理。每个Java对象都由三部分组成:对象头(Object Header)、实例数据(Instance Data)和对齐填充(Padding)。对象头包含对象引用和类型信息,实例数据是对象实际存储...

    计算java对象大小

    总结来说,理解Java对象大小的计算对于优化内存使用、防止内存泄漏以及提高应用程序性能至关重要。开发人员需要了解不同方法的优缺点,并根据实际需求选择合适的方式。同时,应当注意,过于关注单个对象的大小可能...

    计算一个Java对象占用字节数的方法

    本篇文章将深入探讨如何计算Java对象占用的内存字节数,以及影响这一数值的因素。 首先,Java对象在堆内存中由四个部分组成:对象头(A)、基本类型域(B)、引用类型域(C)和填充物(D)。 **对象头(A)**: ...

    java字符串内存计算

    ### Java字符串内存计算 在Java开发中,理解内存管理至关重要,特别是对于字符串处理而言。本文将深入探讨如何在Java中计算字符串所占用的内存空间,包括现有的计算方法、其局限性以及具体的计算公式。 #### 计算...

    java 通过sizeOf计算一个对象的大小

    总的来说,通过`sizeOf`计算Java对象的大小是一项复杂的工作,涉及到JVM内部的内存管理和对象表示。尽管Java API没有直接提供这样的功能,但我们可以借助第三方库或自定义工具来实现。理解对象大小对于优化内存使用...

    统计缓存(java对象所占的内存)大小

    本文将深入探讨如何统计缓存(尤其是Java对象)所占的内存大小,以及这对理解程序内存消耗的重要性。 首先,我们要知道Java对象的内存开销主要由三部分组成:对象头、实例数据和对齐填充。对象头包含对象的类型信息...

    java实现内存动态分配

    堆内存是Java中的全局共享区域,用于存储所有的对象实例和数组。当通过`new`关键字创建一个新的对象时,其实际的数据结构和属性值都在堆中分配。由于堆内存是所有线程共享的,因此对象实例的创建和访问需要考虑线程...

    java 使用静态成员变量计算内存中实例化的对象数目

    在Java编程语言中,了解如何计算内存中实例化对象的数量是一项重要的技能,这对于优化程序性能、理解和管理资源分配至关重要。本篇文章将详细讲解如何利用静态成员变量来追踪和计算一个类在运行时创建的实例数量。 ...

    测试java对象占用内存大小的例子

    本示例主要探讨如何测试Java对象占用的内存大小,以便更好地理解内存使用情况。 首先,`SizeOf.java`可能是一个实现自定义内存大小计算的类。在Java中,由于垃圾回收机制的存在,直接获取对象的内存占用并不像C++等...

    计算java对象的大小的方法

    本文将深入探讨如何计算Java对象的大小,以及这个知识点在实际开发中的应用。 首先,Java对象的大小不仅仅包括其字段的大小,还包括对象头(object header)的大小,对于HotSpot虚拟机,它包含了对齐填充、Mark ...

    java-sizeof-0.0.4:一个查看java对象占用内存大小

    "java-sizeof-0.0.4"是一个用于分析Java对象内存占用的工具,它可以帮助开发者更好地理解对象在运行时的内存消耗。这个工具提供了查看对象实例大小的能力,这对于调试和性能优化非常有用。"java-sizeof-0.0.4"包含三...

    JVM内存结构、Java内存模型、Java对象模型1

    Java虚拟机(JVM)内存结构是Java程序运行的基础,它将内存划分为若干个不同的数据区域,包括...而Java对象模型则决定了对象在内存中的布局和访问方式。每个主题都值得深入研究,以便更好地理解和调试Java程序的行为。

    Java内存机制学习和使用

    除了Java堆内存之外,Java应用程序还需要使用到**本机内存**(Native Memory),这是指JVM之外的内存,主要用于存储JVM自身的元数据、线程栈以及一些非Java对象的数据结构。 - **元数据**:包括类定义、字段信息、...

    深入理解Java 虚拟机内存模型.rar

    - **对象创建与分配**:Java对象通常在堆上创建,通过new关键字或者反射实现。 - **垃圾收集(Garbage Collection, GC)**:自动内存管理,清理不再使用的对象,防止内存泄漏。包括新生代GC(Minor GC)、老年代GC...

    Java 对象(数组)占多大空间(几个字节) 手把手做实验

    总之,Java对象和数组的内存占用取决于JVM的配置、对象的字段、数组的元素类型和长度等因素。开启或关闭压缩选项会影响对象和数组引用的大小,进而影响整体的内存占用。对于内存优化和性能调优来说,了解这些细节至...

    深入理解Java内存模型 pdf 超清版

    - Java堆内存是所有线程共享的,因此要关注内存泄漏问题,避免无用对象占用过多内存。 - 垃圾回收机制负责自动清理不再使用的对象,了解其工作原理有助于优化程序性能。 6. **并发工具类** - Java提供了如`...

    Java获取计算机CPU、内存等信息

    `getHeapMemoryUsage()`和`getNonHeapMemoryUsage()`方法分别返回堆和非堆内存的使用情况,`MemoryUsage`对象提供了获取各个阶段内存大小的方法:初始化大小(`getInit`)、当前使用大小(`getUsed`)、已分配大小(`...

    Java占用内存的研究.pdf

    接着,文档详细分析了Java对象的内存占用情况。每个对象都会在内存中占用一定的空间,用来存储对象的类型指针、哈希码、GC分代年龄、同步锁信息等。尽管这些信息占用的大小在不同的JVM实现中可能有所差异,但一般...

    测量Java对象大小的demo

    本示例“测量Java对象大小的demo”提供了一种方法,通过使用Java的`java.lang.instrument`包来注入`javaagent`,进而利用`Instrumentation`接口测量Java对象的精确内存占用。下面我们将详细探讨这一过程。 首先,`...

Global site tag (gtag.js) - Google Analytics