如何准确计算Java对象的大小
如何准确计算Java对象的大小
原创文章,转载请注明:博客园aprogramer
原文链接:如何准确计算Java对象的大小
- 创建一个有premain方法的agent 类,
- JVM在调用agent类的premain方法时会传入一个Instrumentation 对象,调用Instrumentation的getObjectSize方法
- 把agent类打成一个jar包
- 启动我们的应用程序,使用JVM参数指定agent jar的路径
1. 创建Instrumentation agent类
public static void premain(String args, Instrumentation inst) {
...
}
JVM会在应用程序运行之前调用这个方法(也就是在执行应用程序的main方法之前),JVM会在调用该方法时传入一个实现Instrumentation接口的实例,此时我们就可以调用getObjectSize()方法来计算对象的大小。例如我们要计算Object实例和自定义类型MyObject实例的大小,agent代码如下:
package my;
import java.lang.instrument.Instrumentation; public class MyAgent {
public static void premain(String args, Instrumentation inst) {
Object obj = new Object();
System.out.println("Bytes used by Object:"+ inst.getObjectSize(obj));
System.out.println("Bytes used by MyObject:"+ inst.getObjectSize(new MyObject()));
}
public static void main(String[] args) {
System.out.println("main is over");
}
}
MyObject代码如下:
package my;
public class MyObject{
Object object = new Object();
}
需要注意的是agent类不需要实现任何接口,只需要定义premain方法就行,JVM会自动调用该方法。
2. 把agent类打包成jar包
Premain-Class: my.MyAgent
然后执行一下命令创建jar包
jar -cmf manifest.txt agent.jar my/*
3.使用agent运行应用程序
java -javaagent:agent.jar -cp . my.MyAgent
在32位机器上运行结果如下:
hadoop@32bithost:~/workspace/my/bin$ java -javaagent:agent.jar my.MyAgent
Bytes used by Object:8
Bytes used by MyObject:16
main is over
在64位机器上(不开启指针压缩)运行结果如下:
[genie.yjd@64bithost ~]$ java -XX:-UseCompressedOops -javaagent:agent.jar -cp . my.MyAgent
Bytes used by Object:16
Bytes used by MyObject:24
main is over
在64位机器上(开启指针压缩)运行结果如下:
[genie.yjd@64bithost~]$ java -XX:+UseCompressedOops -javaagent:agent.jar -cp . my.MyAgent
Bytes used by Object:16
Bytes used by MyObject:16
main is over
运行结果显示对于Object对象在32bit机器上占8个字节,在64bit机器上占16个字节,而对于用于一个Object类型成员的MyObject在32bit机器上占用16个字节,而在64bit机器上不开启指针压缩是占用24个字节,开启指针压缩后占用16个字节。
在应用程序中访问Instrumentation对象
在上面的例子中,我们在premain方法中计算对象的大小。可是如果我们想要在应用程序执行期间计算某个对象的大小该怎么办呢?
我们可以这样做,在premain方法中把Instrumentation对象保存在一个static引用中,然后提供一个static方法访问这个实例,代码如下:
public class MyAgent {
private static volatile Instrumentation globalInstr;
public static void premain(String args, Instrumentation inst) {
globalInstr = inst;
}
public static long getObjectSize(Object obj) {
if (globalInstr == null)
throw new IllegalStateException("Agent not initted");
return globalInstr.getObjectSize(obj);
}
}
这样我们就可以在应用程序中调用 MyAgent.getObjectSize()来计算运行时任意实例的大小了。
深度计算对象内存使用
如何准确计算Java对象的大小的更多相关文章
- 计算Java对象内存大小
摘要 本文以如何计算Java对象占用内存大小为切入点,在讨论计算Java对象占用堆内存大小的方法的基础上,详细讨论了Java对象头格式并结合JDK源码对对象头中的协议字段做了介绍,涉及内存模型.锁原理 ...
- Ehcache计算Java对象内存大小
在EHCache中,可以设置maxBytesLocalHeap.maxBytesLocalOffHeap.maxBytesLocalDisk值,以控制Cache占用的内存.磁盘的大小(注:这里Off ...
- JVM —— Java 对象占用空间大小计算
零. 为什么要知道 Java 对象占用空间大小 缓存的实现: 在设计 JVM 内缓存时(不是借助 Memcached. Redis 等), 须要知道缓存的对象是否会超过 JVM 最大堆限制, 假设会超 ...
- 准确计算Java中对象的大小
由于在项目中需要大致计算一下对象的内存占用率(Hadoop中的Reduce端内存占用居高不下却又无法解释),因此深入学习了一下如何准确计算对象的大小. 使用system.gc()和java.lang. ...
- 两种计算Java对象大小的方法
之前想研究一下unsafe类,碰巧在网上看到了这篇文章,觉得写得很好,就转载过来.原文出处是: http://blog.csdn.net/iter_zc/article/details/4182271 ...
- 如何精确地测量java对象的大小-底层instrument API
转载: 如何精确地测量java对象的大小-底层instrument API 关于java对象的大小测量,网上有很多例子,大多数是申请一个对象后开始做GC,后对比前后的大小,不过这样,虽然说这样测量对象 ...
- Java对象的大小及应用类型
基础类型数据的大小是固定的,对于非基本类型的java对象,其大小就值得商榷了. 在java中一个空Object对象的大小是8byte,这个大小只是保存堆中没有任何属性的对象的大小,看下面的语 ...
- java对象内存大小评估
Java对象的内存布局:对象头(Header).实例数据(Instance Data)和对齐填充(Padding).无论是32位还是64位的HotSpot,使用的都是8字节对齐.也就是说每个java对 ...
- 如何查看java对象的大小
有时需要查看java对象占用了多少内存(对象大小),lucene为我们提供了一个很好的工具类,操作简单,如下: int[] s = new int[1024]; System.out.println( ...
随机推荐
- python线程、进程和协程
链接:http://www.jb51.net/article/88825.htm 引言 解释器环境:python3.5.1 我们都知道python网络编程的两大必学模块socket和socketser ...
- python脚本1_给一个半径求圆的面积和周长
#给一个半径,求圆的面积和周长,圆周率3.14 r = int(input('r=')) print('area='+str(3.14*r*r)) print('circumference='+str ...
- HDU 3037 组合数、lucas,逆元
题目链接 题目大意,N颗树上取不超过M个果子,求总方案个数模P的值,P是质数且不超过10w,N,M不超过1e9: 在这里树是被认为不同的,也就是将k(0<=k<=M)个小球放入N个不同的盒 ...
- node-wechat 微信推送消息
https://github.com/nswbmw/node-wechat/blob/master/index.js
- 【lightoj-1046】Rider(BFS)
链接:http://www.lightoj.com/volume_showproblem.php?problem=1046 题意: 给m*n的棋盘,数字k代表这个位置上有棋子,并且一步可以连续跳1-k ...
- 浅析C#中抽象类和接口的区别
声明方法的存在而不去实现它的类被叫做抽象类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况.不能创建abstract 类的实例.然 ...
- 《模式 工程化实现及扩展 (设计模式 C#版)》 - 书摘精要
(P3) 面向对象的典型原则可以划分为两类 —— “面向类”的和“面向包”的: “面向类”的,包括:SRP —— 单一职责原则:OCP —— 开放封闭原则:LSP —— 里氏替换原则:DIP —— 依 ...
- python学习之输出与文件读写
#1. 打印字符串print ("His name is %s"%("Aviad")) #2.打印整数print ("He is %d years o ...
- Scrapy框架及组件描述
Scrapy是用纯Python实现一个为了爬取网站数据.提取结构性数据而编写的应用框架,用途非常广泛. 框架的力量,用户只需要定制开发几个模块就可以轻松的实现一个爬虫,用来抓取网页内容以及各种图片,非 ...
- kali视频学习(11-15)
第四周kali视频(11-15)学习 11.漏洞分析之OpenVAS使用 12.漏洞分析之扫描工具 13.漏洞分析之WEB爬行 14.漏洞分析之WEB漏洞扫描(一) 15.漏洞分析之WEB漏洞扫描(二 ...