java对象内存大小评估
Java对象的内存布局:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。无论是32位还是64位的HotSpot,使用的都是8字节对齐。也就是说每个java对象,占用的字节数都是8的整数倍。(对象头 + 实例数据 + padding) % 8等于0且0 <= padding < 8。在网上看到各种介绍如何手动计算对象大小的文章,总结了几点:
1.基本数据类型占用的字节数,JVM规范中有明确的规定,无论是在32位还是64位的虚拟机,占用的内存大小是相同的。
2.reference类型在32位JVM下占用4个字节,但是在64位下可能占用4个字节或8个字节,这取决于是否启用了64位JVM的指针压缩参数UseCompressedOops。
3.对象头占用8字节
4.开启(-XX:+UseCompressedOops)指针压缩,对象头占12字节; 关闭(-XX:-UseCompressedOops)指针压缩,对象头占16字节。
5.64位JVM上,数组对象的对象头占用24个字节,启用压缩之后占用16个字节。之所以比普通对象占用内存多是因为需要额外的空间存储数组的长度。
6.对象内存布局中的实例数据,不包括类的static字段的大小,因为static字段是属于类的,被该类的所有对象共享。
public class PmDataRecord {
private long beginTime;
private String poId;
private long neIdLong;
public PmDataRecord(long beginTime, String poId, long neIdLong) {
this.beginTime = beginTime;
this.poId = poId;
this.neIdLong = neIdLong;
}
}
import org.openjdk.jol.info.ClassLayout;
import org.openjdk.jol.info.GraphLayout; public class Test { static void print(String message) {
System.out.println(message);
System.out.println("-------------------------");
} public static void main(String[] args) {
PmDataRecord obj = new PmDataRecord(111111111111111L, "12345", 111111111111L); print(ClassLayout.parseInstance(obj).toPrintable()); //查看对象外部信息
print(GraphLayout.parseInstance(obj).toPrintable()); //获取对象总大小
print("size : " + GraphLayout.parseInstance(obj).totalSize());
}
}
打印结果
PmDataRecord object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 09 00 00 00 (00001001 00000000 00000000 00000000) (9)
4 4 (object header) 58 27 64 14 (01011000 00100111 01100100 00010100) (342107992)
8 8 long PmDataRecord.beginTime 111111111111111
16 8 long PmDataRecord.neIdLong 111111111111
24 4 java.lang.String PmDataRecord.poId (object)
28 4 (loss due to the next object alignment)
Instance size: 32 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
-------------------------
PmDataRecord@4bae78d object externals:
ADDRESS SIZE TYPE PATH VALUE
42f2c48 32 PmDataRecord (object)
42f2c68 14640 (something else) (somewhere else) (something else)
42f6598 16 java.lang.String .poId (object)
42f65a8 158768 (something else) (somewhere else) (something else)
431d1d8 24 [C .poId.value [1, 2, 3, 4, 5]
-------------------------
size : 72
-------------------------
引包:
jol-core-0.9.jar
包地址:
http://central.maven.org/maven2/org/openjdk/jol/jol-core/0.9/
java对象内存大小评估的更多相关文章
- Ehcache计算Java对象内存大小
在EHCache中,可以设置maxBytesLocalHeap.maxBytesLocalOffHeap.maxBytesLocalDisk值,以控制Cache占用的内存.磁盘的大小(注:这里Off ...
- 计算Java对象内存大小
摘要 本文以如何计算Java对象占用内存大小为切入点,在讨论计算Java对象占用堆内存大小的方法的基础上,详细讨论了Java对象头格式并结合JDK源码对对象头中的协议字段做了介绍,涉及内存模型.锁原理 ...
- 如何精确地测量java对象的大小-底层instrument API
转载: 如何精确地测量java对象的大小-底层instrument API 关于java对象的大小测量,网上有很多例子,大多数是申请一个对象后开始做GC,后对比前后的大小,不过这样,虽然说这样测量对象 ...
- 如何准确计算Java对象的大小
如何准确计算Java对象的大小 原创文章,转载请注明:博客园aprogramer 原文链接:如何准确计算Java对象的大小 有时,我们需要知道Java对象到底占用多少内存,有人通过连续调用两 ...
- JVM —— Java 对象占用空间大小计算
零. 为什么要知道 Java 对象占用空间大小 缓存的实现: 在设计 JVM 内缓存时(不是借助 Memcached. Redis 等), 须要知道缓存的对象是否会超过 JVM 最大堆限制, 假设会超 ...
- Synchronized加锁、锁升级和java对象内存结构
首先了解一下JMM中定义的内存操作: 一个线程操作数据时候都是从主内存(堆内存)读取到自己工作内存(线程私有的数据区域)中再进行操作.对于硬件内存来说,并没有工作内存和主内存的区分,这都是java内存 ...
- Java对象内存布局
本文转载自Java对象内存布局 导语 首先直接抛出问题 Unsafe.getInt(obj, fieldOffset)中的fieldOffset是什么, 类似还有compareAndSwapX(obj ...
- Java对象内存模型
2 Java对象内存模型 在HotSpot虚拟机中,对象在内存中存储的布局可以分为3块区域:对象头(Header). 实例数据(Instance Data)和对齐填充(Padding). 在 JVM ...
- JAVA 对象内存结构
JAVA对象内存结构 HotSpot虚拟机中,对象在内存中存储的布局可以分为三块区域:对象头(Header).实例数据(Instance Data)和对齐填充(Padding). 对象头 markWo ...
随机推荐
- 今日头条 2018 AI Camp 6 月 2 日在线笔试编程题第二道——两数差的和
题目 给 n 个实数 a_1, a_2 ... a_n, 要求计算这 n 个数两两之间差的绝对值下取整后的和是多少. 输入描述 第一行为一个正整数 n 和一个整数 m.接下来 n 行,第 i 行代表一 ...
- throw er; // Unhandled 'error' event&Error: ENOENT: no such file or directory,
今天做一个文件上传的项目时, 用express-formidable往硬盘里面存文件时, 报 ENOENT:no such file or directory 原因就是程序不能像别的语言一样不存在就 ...
- [boost-2] 智能指针
boost库学习: 智能指针: shared_ptr指针,定义在boost::shared_ptr,如果开发环境支持的话,可以使用memory中的std::shared_ptr. shared_ptr ...
- Dispose的调用顺序
非托管资源的释放顺序. 这是应该先释放 reader 再释放 stream. 或者直接使用using,防止出错 .
- lintcode-91-最小调整代价
91-最小调整代价 给一个整数数组,调整每个数的大小,使得相邻的两个数的差不大于一个给定的整数target,调整每个数的代价为调整前后的差的绝对值,求调整代价之和最小是多少. 注意事项 你可以假设数组 ...
- 【python】实现一个python编程的小时钟!
[本实验内容] 1.GUI.PyQT5介绍2.实现此次实验效果 [一 GUI.PyQt5介绍] 1.Python简介 2.GUI介绍 几个常用的Python GUI库: (1)wxPython (2) ...
- 使用 window.getSelection() 方法获取鼠标划取部分的起始位置和结束位置的问题(高亮后不能正确获取)
如果没有高亮等复杂处理,只需要获取一段文字中选取的字和位置,那么 使用window.getSelection()获取div中选中文字内容及位置 怎么获取textarea中选中文字 则可以满足需求: - ...
- vue2.0中父子组件之间的通信总结
父组件: 子组件: 接受父组件的信息: 向父组件发送事件: (其中slot是插槽,可以将父组件中的<p>123</p>插入进来,如果父组件没有插入的内容,则显示slot内部的内 ...
- 数据结构—栈(Stack)
栈的定义--Stack 栈是只允许在末端进行插入和删除的线性表.栈具有后进先出的特性(LIFO ,Last In Fast Out). 学过数据结构的人都知道:栈可以用两种方式来实现,一种方法是用数组 ...
- 关于label标签的作用
label标签的定义和用法: <label> 标签为 input 元素定义标注(标记). label 元素不会向用户呈现任何特殊效果.不过,它为鼠标用户改进了可用性.如果您在 label ...