前言

一直以来,对java对象大小的概念停留在基础数据类型,比如byte占1字节,int占4字节,long占8字节等,但是一个对象包含的内存空间肯定不只有这些。

假设有类A和B,当new A()或者new B()后,实际占用的java内存是多大呢?下面就对此进行详细分析。

static class A{
String s = new String();
int i = 0;
} static class B{
String s;
int i;
}

对象大小分析

如图1,java对象在内存中占用的空间分为3类, 1. 对象头(Header); 2. 实例数据(Instance Data); 3. 对齐填充(Padding)。而我们常说的基础数据类型大小主要是指第二类实例数据。

图1

对象头

HotSpot虚拟机的对象头包括两部分信息:

markword和klass 。第一部分markword,用于存储对象自身的运行时数据,如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等。 另外一部分是klass类型指针,即对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。

数组长度

如果对象是一个数组, 那在对象头中还必须有一块数据用于记录数组长度,也就是一个int类型的对象,占4字节。

对象头占用空间

1. 在32位系统下,存放Class指针的空间大小是4字节,MarkWord是4字节,对象头为8字节。

2. 在64位系统下,存放Class指针的空间大小是8字节,MarkWord是8字节,对象头为16字节。

3. 在64位开启指针压缩的情况下 -XX:+UseCompressedOops,存放Class指针的空间大小是4字节,MarkWord是8字节,对象头为12字节。

4. 如果对象是数组,那么额外增加4个字节

实例数据

实例数据部分是对象真正存储的有效信息,也是在程序代码中所定义的各种类型的字段内容。无论是从父类继承下来的,还是在子类中定义的,都需要记录起来。

对齐填充

最后一块对齐填充空间并不是必然存在的,也没有特别的含义,它仅仅起着占位符的作用。这是由于HotSpot VM的自动内存管理系统要求对象起始地址必须是8字节的整数倍,换句话说,就是对象的大小必须是8字节的整数倍。

如何查看java对象大小

1. 基于JDK1.8

JDK1.8有一个类`jdk.nashorn.internal.ir.debug.ObjectSizeCalculator`可以评估出对象的大小

// 直接调用静态方法即可使用

ObjectSizeCalculator.getObjectSize(obj)

2. spark库

spark库中有一个类`org.apache.spark.util.SizeEstimator`

// 直接调用静态方法即可使用

SizeEstimator.estimate(obj)

3. 基于JDK1.5的Instrumentation

// 需要编译成jar调用,没有前者方便

案例

分析完对象的组成结构后,再回头来看那个问题

// 对象A: 对象头12B + 内部对象s引用 4B + 内部对象i 基础类型int 4B + 对齐 4B = 24B
// 内部对象s 对象头12B + 2个内部的int类型8B + 内部的char[]引用 4B + 对齐0B = 24B
// 内部对象str的内部对象char数组 对象头12B + 数组长度4B + 对齐0B = 16B
// 总: 对象A 24+ 内部对象s 24B + 内部对象s的内部对象char数组 16B =64B
class A {
String s = new String();
int i = 0;
} // 对象B:对象头12B + 内部对象s引用 4B + 内部对象i 基础类型int 4B + 对齐 4B = 24B
// s没有被分配堆内存空间
// 总: 对象B 24B
class B {
String s;
int i = 0;
}

总结

对象在jvm中不是完全连续的,这是由于GC的原因,总会出现散乱的内存。这就导致了jvm必须为每个对象分配一段内存空间来存储其引用的指针,再结合对象的其他必须的元数据,使得对象在持有真实数据的基础上还需要维护额外的数据。

在写java代码需要小心这些jvm内存陷阱。

参考

// stackoverflow给出的几种计算对象大小方法

https://stackoverflow.com/questions/52353/in-java-what-is-the-best-way-to-determine-the-size-of-an-object

java对象在内存的大小的更多相关文章

  1. Java对象的内存模型(一)

    前言 新人一枚,刚刚入门编程不久,各方面都在学习当中,博文有什么错误的地方,希望我们可以多多交流! 最近,在开发App后台过程中,需要将项目部署到云服务器上.而云服务器的内存大小却只有1G.要如何做到 ...

  2. JVM总结-java对象的内存布局

    在 Java 程序中,我们拥有多种新建对象的方式.除了最为常见的 new 语句之外,我们还可以通过反射机制.Object.clone 方法.反序列化以及 Unsafe.allocateInstance ...

  3. Java对象的内存(一)

    前言 新人一枚,刚刚入门编程不久,各方面都在学习当中,博文有什么错误的地方,希望我们可以多多交流! 最近,在开发App后台过程中,需要将项目部署到云服务器上.而云服务器的内存大小却只有1G.要如何做到 ...

  4. Java对象的内存布局以及对象的访问定位

    一 Java对象的内存布局 在HotSpot虚拟机中,对象在内存中的布局分为3个区域 对象头(Header) Mark Word(在32bit和64bit虚拟机上长度分别为32bit和64bit)存储 ...

  5. 3 Java对象的内存布局以及对象的访问定位

    先来看看Java对象在内存中的布局   一 Java对象的内存布局 在HotSpot虚拟机中,对象在内存中的布局分为3个区域 对象头(Header) Mark Word(在32bit和64bit虚拟机 ...

  6. 灵魂拷问:Java对象的内存分配过程是如何保证线程安全的?(阿里面试)

    JVM内存结构,是很重要的知识,相信每一个静心准备过面试的程序员都可以清楚的把堆.栈.方法区等介绍的比较清楚. 上图,是一张在作者根据<Java虚拟机规范(Java SE 8)>中描述的J ...

  7. JAVA | Java对象的内存分配过程是如何保证线程安全的?

    JAVA | Java对象的内存分配过程是如何保证线程安全的? 专注于Java领域优质技术,欢迎关注 作者 l Hollis 来源 l Hollis(ID:hollischuang) JVM内存结构, ...

  8. Java对象的内存布局

    对象的内存布局 平时用java编写程序,你了解java对象的内存布局么? 在HotSpot虚拟机中,对象在内存中存储的布局可以分为3块区域: 对象头 实例数据 对齐填充 对象头 对象头包括两部分信息: ...

  9. java对象在内存中的分配

    java对象在内存中的分配 http://blog.csdn.net/qq_30753945/article/details/54974899

随机推荐

  1. eclipse的new server里tomcat7.0根本选不上解决方法

    创建Tomcat v7.0 Server 不能进行下一步. 解决方法: 1.退出 eclipse 2.到[工程目录下]/.metadata/.plugins/org.eclipse.core.runt ...

  2. .NET Core 2.0 官方下载地址及中文教程

    开发.net core 应用需要安装.NET Core 2.0 SDK http://www.microsoft.com/net/download/core#/sdk 电脑上运行 .net core ...

  3. spring的bean容器加载

    1.在单独使用的时候可以通过ClassPathXmlApplicationContext(“配置文件.xml”);来启动容器. 2.在MVC下是通过启动servlet容器,初始化DispatcherS ...

  4. SVN 取消版本控制并添加至忽略列表

    忽略已经版本控制的文件忽略文件和目录 起因: 由于项目中的IDE Jdeveloper在某些指定目录下面会生成server.xml以及common文件夹,且包含一个名为bc4j.xcfg的文件,每次当 ...

  5. iOS UI基础-4.1应用程序管理 字典转Model

    用模型取代字典 使用字典的坏处 一般情况下,设置数据和取出数据都使用“字符串类型的key”,编写这些key时,编辑器没有智能提示,需要手敲 dict[@"name"] = @&qu ...

  6. win10安装激活与关闭自动更新

    1.安装时即使选择了不保留任何文件,也不会删除掉非c盘里的东西 2.安装后需要执行KMS10_Crack2激活下 3.关闭自动更新. 在服务中禁用 https://zhidao.baidu.com/q ...

  7. 33. Search in Rotated Sorted Array(二分查找)

    Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. (i.e. ...

  8. (二)github的价值意义篇

    为什么需要社会化编程? 如果您是程序员面试官,两者之间你会选择哪一位呢? 能查看以前所写代码的程序员 or 无法查看的程序员 精通最新软件的程序员 or 不精通的程序员 对语言或软件差异带来的不同文化 ...

  9. 20145220韩旭飞《网络对抗》Exp8 Web基础

    20145220韩旭飞<网络对抗>Exp8 Web基础 Web前端:HTML基础 首先,我们的Web开发是基于Apache服务器进行的,所以对于Apache的基本操作我们是应该要掌握的,对 ...

  10. 微信小程序——2、配置json文件

    配置文件详解 主配置文件app.json 主配置文件位于主目录中,用于进行全局配置.包括页面文件的路径.窗口表现.设置网络超时时间.设置多tab等 下面通过微信最初自带小程序来学习 { "p ...