如何计算Java对象占用了多少空间?

在Java中没有sizeof运算符,所以没办法知道一个对象到底占用了多大的空间,但是在分配对象的时候会有一些基本的规则,我们根据这些规则大致能判断出来对象大小。

对象头

对象的头部至少有两个WORD,如果是数组的话,那么三个WORD,内容如下:

  1. 对象的HashCode,锁信息等
  2. 到对象类型数据的指针
  3. 数组的长度(如果是数组的话)

规则

首先,任何对象都是8字节对齐,属性按照[long,double]、[int,float]、[char,short]、[byte,boolean]、reference的顺序存放,举个例子:


  1. public class Test { 
  2.     byte a; 
  3.     int b; 
  4.     boolean c; 
  5.     long d; 
  6.     Object e; 

如果这个对象的属性按照顺序存放的话,要占用的空间为:head(8) + a(1) + padding(3) + b(4) + c(1) +
padding(7) + d(8) + e(4) + padding(4) = 40。但是按照这个规则得到:head(8) + d(8) +
b(4) + a(1) + c(1) + padding(2) + e(4) + padding(4) = 32。可以看到节省了不少空间。

在涉及继承关系的时候有一个最基本的规则:首先存放父类中的成员,接着才是子类中的成员,举个例子:


  1. class A { 
  2.     long a; 
  3.     int b; 
  4.     int c; 
  5. class B extends A { 
  6.     long d; 

这样存放的顺序及占用空间如下:head(8) + a(8) + b(4) + c(4) + d(8) =
32。那如果父类中的属性不够八个字节怎么办?这样就有了新的一条规则:父类中最后一个成员与子类的第一个成员的间隔如果不够4个字节,此时需要扩展到4
个字节的基本单位,举个例子:


  1. class A { 
  2.     byte a; 
  3. class B extends A { 
  4.     byte b; 

那么此时占用的空间如下:head(8) + a(1) + padding(3) + b(1) + padding(3) =
16。显然这种方式比较浪费空间,那么就有了:如果子类的第一个成员是double或者long,并且父类并没有用完8个字节,JVM会破坏规将较小的数
据填充到该空间,举个例子:


  1. class A { 
  2.     byte a; 
  3. class B extends A { 
  4.     long b; 
  5.     short c; 
  6.     byte d; 

此时占用的空间如下:head(8) + a(1) + padding(3) + c(2) + d(1) + padding(1) + b(8) = 24。

来源:51CTO

时间: 2024-12-24 06:09:56

如何计算Java对象占用了多少空间?的相关文章

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

本文实例讲述了如何计算(或者说,估算)一个Java对象占用的内存数量的方法.分享给大家供大家参考.具体分析如下: 通常,我们谈论的堆内存使用的前提是以"一般情况"为背景的.不包括下面两种情形:   某些情况下,JVM根本就没有把Object放入堆中.例如:原则上讲,一个小的thread-local对象存在于栈中,而不是在堆中. 被Object占用内存的大小依赖于Object的当前状态.例如:Object的同步锁是否生效,或者,Object是否正在被回收. 我们先来看看在堆中单个的Obj

一个Java对象到底占多大内存?(转)

最近在读<深入理解Java虚拟机>,对Java对象的内存布局有了进一步的认识,于是脑子里自然而然就有一个很普通的问题,就是一个Java对象到底占用多大内存? 在网上搜到了一篇博客讲的非常好:http://yueyemaitian.iteye.com/blog/2033046,里面提供的这个类也非常实用: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35

java 各个常规类型的占用的内存空间

问题描述 java 各个常规类型的占用的内存空间?如题. 解决方案 汗,写错了..重新发一遍吧.长度的单位为byte. byte(字节型) 长度:1, 范围:-128-127 short(短整型) 长度: 2, 范围: -32768-32767 int(整型) 长度:4, 范围: -2147483648-2147483647 long(长整型) 长度: 8 , 范围: -9223372036854775808 ~ 9223372036854775807 float(浮点型) 长度: 4 , 范围

Java对象及元素的存储区域

在JAVA平台上开发应用程序的时候,有一个很大的特点就是其是在应用程序运行的时候才建立对象. 换句话说,在程序运行的时候,才会最终确定对象的归属,即对象应该存储在什么地方.由于存储在不同 的区域,其在性能上会有所不同.为此作为Java程序开发人员需要了解各个存储区域的特点以及对性能的 影响.然后再根据需要来调整应用程序的区域分配.总的来说,在操作系统中有五个地方可以用来保存应 用程序运行中的数据.这类区域的特点以及对性能的影响分析如下. 存储区域一:寄存器 虽然同在内存中,但是不同的区域由于用途

Java对象的生命周期与作用域的讨论(转)

导读: Java对象的生命周期大致包括三个阶段:对象的创建,对象的使用,对象的清除.因此,对象的生命周期长度可用如下的表达式表示:T = T1 + T2 +T3.其中T1表示对象的创建时间,T2表示对象的使用时间,而T3则表示其清除时间.由此,我们可以看出,只有T2是真正有效的时间,而T1.T3则是对象本身的开销.下面再看看T1.T3在对象的整个生命周期中所占的比例. 我们知道,Java对象是通过构造函数来创建的,在这一过程中,该构造函数链中的所有构造函数也都会被自动调用.另外,默认情况下,调用

认识JVM--第二篇-java对象内存模型

   前一段写了一篇<认识JVM>,不过在一些方面可以继续阐述的,在这里继续探讨一下,本文重点在于在heap区域内部对象之间的组织关系,以及各种粒度之间的关系,以及JVM常见优化方法,文章目录如下所示: 1.回顾--java基础的对象大概有哪些特征 2.上一节中提到的Class加载是如何加载的 3.一个对象放在内存中的是如何存放的 4.调用的指令分析 5.对象宽度对其问题及空间浪费 6.指令优化   正文如下: 1.回顾--java基础的对象大概有哪些特征?     相信学习过java或者叫做

如何精确地测量java对象的大小-底层instrument API

关于java对象的大小测量,网上有很多例子,大多数是申请一个对象后开始做GC,后对比前后的大小,不过这样,虽然说这样测量对象的大小是可行的,不过未必是完全准确的,因为过程中包含对象本身的开销,也许你运气好,正好能碰上,差不多,不过这种测试往往显得十分的笨重,因为要写一堆代码才能测试一点点东西,而且只能在本地测试玩玩,要真正测试实际的系统的对象大小这样可就不行了,本文说说java一些比较偏底层的知识,如何测量对象大小,java其实也是有提供方法的.注意:本文的内容仅仅针对于Hotspot VM,如

java对象静态变量放在jvm的什么区域?

问题描述 请问:1.java对象静态变量在jvm的什么区?2.如果一个javabaen有若干静态变量,那new这个javabean的时候,静态变量占用内存是否会不断增加?如:private Class User{ public static final String TEST= "0";//待处理 private String name; private String age; //get&&set}多次调用new User()的时候TEST变量的内存占用是否会增加,还

源码分析:Java对象的内存分配

Java对象的分配,根据其过程,将其分为快速分配和慢速分配两种形式,其中快速分配使用无锁的指针碰撞技术在新生代的Eden区上进行分配,而慢速分配根据堆的实现方式.GC的实现方式.代的实现方式不同而具有不同的分配调用层次.  下面就以bytecodeInterpreter解释器对于new指令的解释出发,分析实例对象的内存分配过程: 一.快速分配 1.实例的创建首先需要知道该类型是否被加载和正确解析,根据字节码所指定的CONSTANT_Class_info常量池索引,获取对象的类型信息并调 用is_