一、计算对象大小的方法

Java中如何计算对象的大小呢,找到了4种方法:

1.java.lang.instrument.Instrumentation的getObjectSize方法;

2.BTraceUtils的sizeof方法;

3.http://yueyemaitian.iteye.com/blog/2033046中提供的代码计算;

4.https://github.com/mingbozhang/memory-measurer提供的工具包;

本质上java.lang.instrument.Instrumentation的使用是其他三种方法的基础,但是该类中的方法getObjectSize只是计算了对象本身,JDK注释描述:

Returns an implementation-specific approximation of the amount of storage consumed by
the specified object. The result may include some or all of the object's overhead,
and thus is useful for comparison within an implementation but not between implementations.

第2种是使用BTrace的方法,可以对生产环境的程序进行检测,但是BTraceUtils的sizeof实现上直接调用的还是java.lang.instrument.Instrumentation的getObjectSize方法,所以还是存在第1种方法的问题。第3中方法可以计算数组的大小,但是无法计算HashMap等对象。第4种方法支持对HashMap等常见对象的大小计算。

第1种方法网上可以找到很多资料可以参考,第3中方法链接博文内容已经很详细。这里给出第2中方法以及第4种方法的使用步骤。

二、BTrace中计算对象大小

我使用的BTrace是Java VisualVM中的插件版。VisualVM打开方式为命令行输入jvisualvm,

安装插件BTrace,安装成功的话,查看Plugin窗口

安装插件这部分工作这里就不说了,下面演示如何使用。

启动tomcat,在VisualVM左侧中选择刚刚启动的tomcat,右键弹框中选择Trace application

这时右侧将会打开BTrace窗口:

上面右侧代码是BTrace用于检测com.test.data.TestBtrace类在执行search方法后返回值的大小。

import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*; @BTrace public class Sizeof {
@OnMethod(
clazz="com.test.data.TestBtrace",
method = "search", location = @Location(Kind.RETURN)
)
public static void onnew(@Return Object obj) {
println(Strings.concat("object of: ", Reflective.name(Reflective.classOf(obj))));
println(Strings.concat("size: ", Strings.str(sizeof(obj))));
}
}

点击start按钮执行成功显示如下(红框内),说明已经进入监视状态:

执行tomcat上面的com.test.data.TestBtrace中search方法,BTrace控制台打印出了返回结果对象的类型以及对象大小,每次都是48 bytes。

具体BTrace脚本说明以及例子可以参考:https://github.com/mingbozhang/btrace

其中docs有帮助文档,samples有例子。

三、使用MemoryMeasurer计算对象大小

到https://github.com/mingbozhang/memory-measurer上面将源码下载到本地,编译需要本地预先安装java,maven。

1.加入检测代码到目标代码中

这里的使用方法不像BTrace的低侵入,需要在代码中加入检测代码:

long memory = MemoryMeasurer.measureBytes(objectToTest);

通过输出日志或者其他方式将上面代码中变量memory内容获取到。

2.启动TOMCAT是在JAVA_OPTS中加入:

-javaagent:<实际目录>/memory-measurer-0.1.0-SNAPSHOT.jar

3.启动TOMCAT,操作application并查看打印出的待检测对象的大小信息。

使用该方法测试出的com.test.data.TestBtrace中search方法返回结果对象大小为:349264 bytes

注意:由于此项目依赖guava包,如果待测试代码直接main方法启动使用target生成的memory-measurer-0.1.0-SNAPSHOT.jar,如果是检测tomcat上的application则需要使用target生成的memory-measurer-0.1.0-SNAPSHOT-jar-with-dependencies.jar。

四、思考

找到的这几种方法第1、2中是比较官方一些的方法。3、4是个人写的代码或者工具。如果寻找容器对象真实大小这个需求是个迫切需求,为什么没有看到官方版本的对象真实大小计算工具?

Java中计算对象的大小的更多相关文章

  1. JAVA中JavaBean对象之间属性拷贝的方法

    JAVA中JavaBean对象之间的拷贝通常是用get/set方法,但如果你有两个属性相同的JavaBean或有大部分属性相同的JavaBean,对于这种情况,可以采用以下几个简便方法处理. 下面对这 ...

  2. 浅谈Java中的对象和引用

    浅谈Java中的对象和对象引用 在Java中,有一组名词经常一起出现,它们就是“对象和对象引用”,很多朋友在初学Java的时候可能经常会混淆这2个概念,觉得它们是一回事,事实上则不然.今天我们就来一起 ...

  3. 【译】Java中的对象序列化

    前言 好久没翻译simple java了,睡前来一篇. 译文链接: http://www.programcreek.com/2014/01/java-serialization/ 什么是对象序列化 在 ...

  4. java中直接打印对象

    java中直接打印对象,会调用对象.toString()方法.如果没有重写toString()方法会输出"类名+@+hasCode"值,hasCode是一个十六进制数 //没有重写 ...

  5. 如何使用java中的对象

    使用java中的对象,分2步: 1.创建一个对象: 2.使用对象的属性和方法. 见下面的示例代码: package com.imooc; //1.定义一个类 public class Telphone ...

  6. Java中String对象的不可变性

    首先看一个程序 package reverse; public class Reverse { public static void main(String[] args) { String c1=n ...

  7. JAVA中JavaBean对象之间拷贝的方法

    JAVA中JavaBean对象之间的拷贝通常是用get/set方法,但如果你有两个属性相同的JavaBean或有大部分属性相同的JavaBean,有个更简便的方法,他们之间的拷贝可以通过copyPro ...

  8. Java中的对象池技术

    java中的对象池技术,是为了方便快捷地创建某些对象而出现的,当需要一个对象时,就可以从池中取一个出来(如果池中没有则创建一个),则在需要重复重复创建相等变量时节省了很多时间.对象池其实也就是一个内存 ...

  9. 【学习笔记】Java中生成对象的5中方法

    概述:本文介绍以下java五种创建对象的方式: 1.用new语句创建对象,这是最常用的创建对象的方式. 2.使用Class类的newInstance方法 3.运用反射手段,调用java.lang.re ...

随机推荐

  1. yii2定时任务不执行,报错PHP date调用警告:It is not safe to rely on the system's timezone settings

    It is not safe to rely on the system's timezone settings 在写php程序中有时会出现这样的警告:PHP Warning: date(): It ...

  2. Appium 自动化测试(2)--环境安装:安装Android模拟器

    一.安装java 环境-JDK 略,自行百度安装. 二.安装Android SDK Android SDK提供给我们API库和开发工具构建,测试和调试应用程序,Android.简单来讲,Android ...

  3. LightOJ - 1248 期望

    题意:有一个n面筛子,每次扔一下,每面概率相同,要求扔出n面的期望次数 题解:和第三篇论文里的例题一样,算从第i个到第i+1个的概率是(n-i)/n,n面中找n-i个没有扔到过的,期望是n/(n-i) ...

  4. WSL安装xfce4

    参考:https://github.com/Microsoft/WSL/issues/637 安装组件 1. win10 上安装 Xming https://sourceforge.net/proje ...

  5. mysql查询结果带上序号

    select (@i:=@i+1) as rownum,t1.id ","from mega_user t1,(select @i:=0) t2 order by t1.gold ...

  6. 【lightoj-1046】Rider(BFS)

    链接:http://www.lightoj.com/volume_showproblem.php?problem=1046 题意: 给m*n的棋盘,数字k代表这个位置上有棋子,并且一步可以连续跳1-k ...

  7. LeetCode OJ:Lowest Common Ancestor of a Binary Tree(最近公共祖先)

    Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. According ...

  8. UI- UINavigationController UITabBarController 使用总结

    #pragma mark - UINavigationController UITabBarController  ====================================== 控制器 ...

  9. Arcgis for javascript map操作addLayer详解

    本节的内容很简单,说说Arcgis for Javascript里面map对象的addLayer方法.在for JS的API中,addLayer方法有两种,如下图: addLayer方法 在addLa ...

  10. EasyDSS流媒体服务器出现no compatible source was found for this media问题的解决

    在EasyDSS流媒体服务器的客户反馈中,我们遇到这样一个现象,在chrome中经常会出现RTMP/HLS流无法播放的问题: 这个问题复现的几率比较低,因为chrome禁止了flash的加载,这也从另 ...