java对象在内存的大小
前言
一直以来,对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给出的几种计算对象大小方法
java对象在内存的大小的更多相关文章
- Java对象的内存模型(一)
前言 新人一枚,刚刚入门编程不久,各方面都在学习当中,博文有什么错误的地方,希望我们可以多多交流! 最近,在开发App后台过程中,需要将项目部署到云服务器上.而云服务器的内存大小却只有1G.要如何做到 ...
- JVM总结-java对象的内存布局
在 Java 程序中,我们拥有多种新建对象的方式.除了最为常见的 new 语句之外,我们还可以通过反射机制.Object.clone 方法.反序列化以及 Unsafe.allocateInstance ...
- Java对象的内存(一)
前言 新人一枚,刚刚入门编程不久,各方面都在学习当中,博文有什么错误的地方,希望我们可以多多交流! 最近,在开发App后台过程中,需要将项目部署到云服务器上.而云服务器的内存大小却只有1G.要如何做到 ...
- Java对象的内存布局以及对象的访问定位
一 Java对象的内存布局 在HotSpot虚拟机中,对象在内存中的布局分为3个区域 对象头(Header) Mark Word(在32bit和64bit虚拟机上长度分别为32bit和64bit)存储 ...
- 3 Java对象的内存布局以及对象的访问定位
先来看看Java对象在内存中的布局 一 Java对象的内存布局 在HotSpot虚拟机中,对象在内存中的布局分为3个区域 对象头(Header) Mark Word(在32bit和64bit虚拟机 ...
- 灵魂拷问:Java对象的内存分配过程是如何保证线程安全的?(阿里面试)
JVM内存结构,是很重要的知识,相信每一个静心准备过面试的程序员都可以清楚的把堆.栈.方法区等介绍的比较清楚. 上图,是一张在作者根据<Java虚拟机规范(Java SE 8)>中描述的J ...
- JAVA | Java对象的内存分配过程是如何保证线程安全的?
JAVA | Java对象的内存分配过程是如何保证线程安全的? 专注于Java领域优质技术,欢迎关注 作者 l Hollis 来源 l Hollis(ID:hollischuang) JVM内存结构, ...
- Java对象的内存布局
对象的内存布局 平时用java编写程序,你了解java对象的内存布局么? 在HotSpot虚拟机中,对象在内存中存储的布局可以分为3块区域: 对象头 实例数据 对齐填充 对象头 对象头包括两部分信息: ...
- java对象在内存中的分配
java对象在内存中的分配 http://blog.csdn.net/qq_30753945/article/details/54974899
随机推荐
- 第2章 2.n物理层--数据通信基础知识总结
数据通信基础知识总结
- 换个字体解决Dreamweaver文字选不中的问题
在使用Dreamweaver时,有时我们要选中一些字符进行编辑或删除,光标在英文字上面可以选中,在中文字上面就选不中,郁闷吧.比如在编辑下面这段文字的时候,如图所示, 想选中“你难得已经忘了吗?”,当 ...
- CSS 3列等高
方法1: <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"&g ...
- iOS 网易彩票-4设置模块一
概述 基本上,每一款APP都有相应的设置模块.怎么设置才能更灵活和通用呢,这也是大家一直思考的.下面说说在网易彩票中,设置模块的设置思想. 基本上有三种方案: static cell(呆板,完全没有动 ...
- 软件包管理:rpm包管理-yum在线管理-IP地址配置和网络yum源
只需告诉系统你想安装那个包,剩下的所有依赖问题yum都会解决. 有些情况下不能上网,但可以使用光盘. centos的yum是免费的.redhatyum付费. yum管理的其实同样是rpm包.并没有yu ...
- 76. Minimum Window Substring(hard 双指针)
Given a string S and a string T, find the minimum window in S which will contain all the characters ...
- ADO.NET知识学习总结
1. 概述 使用的命名空间: System.Data.SqlClient 连接字符串 服务器/数据库实例+数据库名称+安全信息+用户名+密码 可参考http://www.connectio ...
- javashop技术培训总结,架构介绍,Eop核心机制
javashop技术培训一.架构介绍1.Eop核心机制,基于spring的模板引擎.组件机制.上下文管理.数据库操作模板引擎负责站点页面的解析与展示组件机制使得可以在不改变核心代码的情况下实现对应用核 ...
- jquery checkbox相关 prop方法
jquery checkbox相关 prop方法 firefox中 checkbox属性checked="checked"已有,但复选框却不显示打钩的原因复选框绑定了click事件 ...
- Oracle 11g调用函数几种常用方法
1. 该函数接受3个可选参数,返回3个数字的和 CREATE OR REPLACE FUNCTION add_three_numbers ( a NUMBER:=0, b NUMBER:=0, c N ...