Java - 如何获取对象大小

有没有一种简单的方法获取特定对象的大小?

于是发现了这么个东西:

光看了下该方法的声明,这不就是获取对象的大小么,于是没想太多,心想这下问题变得简单了,弄了个premain方法初始化Instrumentation:

    public class ObjectSizeUtils {

    private static Instrumentation inst = null;

    public static void premain(String agentArgs, Instrumentation inst) {
        ObjectSizeUtils.inst = inst;
    }

    public static long sizeOf(Object o){
        if(inst == null) throw new IllegalStateException("not initialized yet");
        return inst.getObjectSize(o);
    }
}

export jar并在MANIFEST.MF中加上:

Premain-class: pac.testcase.utils.ObjectSizeUtils
Can-Redefine-Classes: false

随便写一个实体类,用来测试:

class Person{
    private  String name;
    private String life;

    public String getName() {return name;}
    public void setName(String name) {this.name = name;}
    public String getLife() {return life;}
    public void setLife(String life) {this.life = life;}
}

好了,在运行参数中加上-javaagent,执行看看会输出什么:

    @Test
    public void testSizeUtils(){
        Person person = new Person("Alvez","make me death before you make me old");
        logger.info(String.valueOf(sizeOf(person)));
        logger.info(String.valueOf(sizeOf(person.getName())));
        logger.info(String.valueOf(sizeOf(person.getLife())));
    }

    static final Logger logger = LoggerFactory.getLogger(ObjectSizeUtils.class);

结果....

为什么person的属性比person还大? 等等,name和life的大小好像也有问题....

回去翻教科书发现事情并不是我希望的那样,我需要把对象里面的元素的大小全部加起来才能达到我要的效果....

看来还需要亲自解决一些事情,于是:

public class ObjectSizeUtils {

    private static Instrumentation inst = null;

    public static void premain(String agentArgs, Instrumentation inst) {
        ObjectSizeUtils.inst = inst;
    }

    public static long sizeOf(Object o) throws IllegalAccessException {
    if(inst == null) throw new IllegalStateException("not initialized yet");
        SizeCounter sizeCounter = new SizeCounter();
        sizeOf(o, sizeCounter);
        return sizeCounter.getSize();
    }

    public static void sizeOf(Object o,SizeCounter sizeCounter) throws IllegalAccessException {
        if(o!=null){
            sizeCounter.addSize(inst.getObjectSize(o));
            Class c = o.getClass();
            Field[] fields = c.getDeclaredFields();
            for (Field f : fields) {
                int mod = f.getModifiers();
                if(Modifier.isStatic(mod) || f.getType().isPrimitive()){
                    continue;
                }
                f.setAccessible(true);
                Object o1 = f.get(o);
                sizeOf(o1,sizeCounter);
            }
        }
    }
    
}

class SizeCounter{
        private long size;

    public long getSize() {
        return size;
    }

    public void setSize(long size) {
        this.size = size;
    }

    public void addSize(long size){
        this.setSize(this.getSize() + size);
    }
}

这段代码并不完整,还有很多因素并没有考虑进去,大体思路差不多就是这样。

时间: 2024-11-06 21:04:44

Java - 如何获取对象大小的相关文章

Java反射获取对象VO的属性值(通过Getter方法)

有时候,需要动态获取对象的属性值. 比如,给你一个List,要你遍历这个List的对象的属性,而这个List里的对象并不固定.比如,这次User,下次可能是Company. e.g. 这次我需要做一个Excel导出的工具类,导出的批量数据是以List类型传入的,List里的对象自然每次都不同,这取决于需要导出什么信息. 为了使用方便,将对象的属性名与属性值存于Map当中,使用时就可以直接遍历Map了. 此次的思路是通过反射和Getter方法取得值,然后记录在一个Map当中. Kick start

Java中比较对象大小的两种实现方式

引入原因: Java中的对象,正常情况下,只能进行比较:== 或!= ,不能使用 < 或 > ,但是在开发时需要用到比较对象的大小 1.Comparable接口的使用(自然排序) 1.像String .包装类等实现了Comparable接口,重写了compareTo()方法,给出了比较两个对象大小的方法 2.像String .包装类等重写了compareTo()方法后,默认执行了从小到大的排序 3.重写compareTo()的规则: 如果当前对象this大于形参对象obj,则返回正整数,如果当

java反射获取对象的属性值和对象属性中的子属性值

近段时间在做web项目,前端使用的是jQuery EasyUI. 为方便需要,准备做一个前端通用的Datagird导出Excel功能,博主也考虑过思路和最终功能,1.前端选中行导出:2.当前页导出:3.当前过滤条件导出. 想偷懒在网上找找已有的代码改改,发现大部分只能满足个别需求,使用JS导出只能满足前端,使用代码才能实现3功能. ...... 好了,说了一堆废话,回归正题,本文是在做通用自定义字段导出时所需要,根据属性名去查找对象和子对象,找到对应属性值,抓取回来放到Excel中. 直接上代码

第六课 JAVA反射获取对象属性和方法(通过配置文件)

Service1.java package reflection; public class Service1 { public void doService1(){ System.out.println("业务方法1"); } } Service2.java package reflection; public class Service2 { public void doService2(){ System.out.println("业务方法1"); } } s

C# 获取对象 大小 Marshal.SizeOf (sizeof 只能在不安全的上下文中使用)

C# 能否获取一个对象所占内存的大小? 今日,在项目重构的时候忽然想到一个问题,一个类哪些成员的增加,会影响一个类所占内存的大小?C#有没有办法知道一个对象占多少内存呢? 第一个问题:很快想到是类的非静态的字段.属性. 第二个问题:首先想到的是sizeof(). 下面开始验证,首先来验证值类型,验证代码如下: int size = sizeof (int); //4个字节 注意点:sizeof 运算符仅适用于值类型,而不适用于引用类型.sizeof 运算符只能在不安全代码块中使用.如下面的代码将

第五课 JAVA反射获取对象属性和方法

package com.hero; import java.lang.reflect.Field; public class TestReflction5 { public static void main(String[] args) { Hero h =new Hero(); //使用传统方式修改name的值为gareen h.name = "gareen"; try { //获取类Hero的名字叫做name的字段 Field f1= h.getClass().getField(&

Java中计算对象的大小

一.计算对象大小的方法 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

java 获取屏幕大小

使用Java AWT类可以很方便取得屏幕分辨率及可用屏幕大小. 01.Dimension scrSize=Toolkit.getDefaultToolkit().getScreenSize();   此语句可取得屏幕实际大小.如屏幕分辨率是1024*768时,scrSize.width的值为1024,scrSize.height的值为768. 01.Insets scrInsets=Toolkit.getDefaultToolkit().getScreenInsets(GraphicsEnvir

聊聊JVM(三)两种计算Java对象大小的方法

这篇说说如何计算Java对象大小的方法.之前在聊聊高并发(四)Java对象的表示模型和运行时内存表示 这篇中已经说了Java对象的内存表示模型是Oop-Klass模型. 普通对象的结构如下,按64位机器的长度计算 1. 对象头(_mark), 8个字节 2. Oop指针,如果是32G内存以下的,默认开启对象指针压缩,4个字节 3. 数据区 4.Padding(内存对齐),按照8的倍数对齐 数组对象结构是 1. 对象头(_mark), 8个字节 2. Oop指针,如果是32G内存以下的,默认开启对