问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

如何查看java对象所占的内存大小

发布网友 发布时间:2022-05-06 06:51

我来回答

1个回答

热心网友 时间:2022-06-28 23:00

我们为什么想要知道对象所占对内存的大小呢? (1)做一些cache的时候,我们不可能把数据库的所有的数据都缓存到内存里面,我们要估计缓存的大小。 (2)内存泄露的时候,我们可以查看某些对象的大小来定位问题,当然还有其他的更有效的方式,比如使用MAT分析mp文件 (3)根据jvm的堆内存设置,我们可以知道最多可以创建多少个对象。 从jdk5开始,提供了Instrumentation API,它有一个叫做getObjectSize()的方法,但是,这个方法存在两个问题: (1)不可以直接使用。必须要实现一个Instrumentation Agent,还得放到jar包里面。 (2)它只能返回单个对象的大小,不能返回内部包含的子对象的大小。 完整的代码如下: package com.bj58.test; import java.lang.instrument.Instrumentation; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.IdentityHashMap; import java.util.Map; import java.util.Stack; public class SizeOfAgent { static Instrumentation inst; /** initializes agent */ public static void premain(String agentArgs, Instrumentation instP) { inst = instP; } /** * Returns object size without member sub-objects. * * @param o * object to get size of * @return object size */ public static long sizeOf(Object o) { if (inst == null) { throw new IllegalStateException( "Can not access instrumentation environment.\n" + "Please check if jar file containing SizeOfAgent class is \n" + "specified in the java's \"-javaagent\" command line argument."); } return inst.getObjectSize(o); } /** * Calculates full size of object iterating over its hierarchy graph. * * @param obj * object to calculate size of * @return object size */ public static long fullSizeOf(Object obj) { Map<Object, Object> visited = new IdentityHashMap<Object, Object>(); Stack<Object> stack = new Stack<Object>(); long result = internalSizeOf(obj, stack, visited); while (!stack.isEmpty()) { result += internalSizeOf(stack.pop(), stack, visited); } visited.clear(); return result; } private static boolean skipObject(Object obj, Map<Object, Object> visited) { if (obj instanceof String) { // skip interned string if (obj == ((String) obj).intern()) { return true; } } return (obj == null) // skip visited object || visited.containsKey(obj); } private static long internalSizeOf(Object obj, Stack<Object> stack, Map<Object, Object> visited) { if (skipObject(obj, visited)) { return 0; } visited.put(obj, null); long result = 0; // get size of object + primitive variables + member pointers result += SizeOfAgent.sizeOf(obj); // process all array elements Class clazz = obj.getClass(); if (clazz.isArray()) { if (clazz.getName().length() != 2) {// skip primitive type array int length = Array.getLength(obj); for (int i = 0; i < length; i++) { stack.add(Array.get(obj, i)); } } return result; } // process all fields of the object while (clazz != null) { Field[] fields = clazz.getDeclaredFields(); for (int i = 0; i < fields.length; i++) { if (!Modifier.isStatic(fields[i].getModifiers())) { if (fields[i].getType().isPrimitive()) { continue; // skip primitive fields } else { fields[i].setAccessible(true); try { // objects to be estimated are put to stack Object objectToAdd = fields[i].get(obj); if (objectToAdd != null) { stack.add(objectToAdd); } } catch (IllegalAccessException ex) { assert false; } } } } clazz = clazz.getSuperclass(); } return result; } } 然后我们可以做一个测试: public class Test { static class Person{ private int id; private String name; private String address; public Person(int id, String name, String address) { this.id = id; this.name = name; this.address = address; } } public static void main(String[] args) throws Exception { Person p = new Person(12, "xujsh","bj"); long size = SizeOfAgent.fullSizeOf(p); System.out.println(size); } } 切换到命令行: D:\workspace\objsize\src>java -version java version "1.6.0_22" Java(TM) SE Runtime Environment (build 1.6.0_22-b04) Java HotSpot(TM) Client VM (build 17.1-b03, mixed mode, sharing) D:\workspace\objsize\src>javac com/bj58/test/*.java D:\workspace\objsize\src>jar -cvfm size.jar MANIFEST.MF com/bj58/test/* 标明清单(manifest) 增加:com/bj58/test/SizeOfAgent.class(读入= 3119) (写出= 1698)(压缩了 45%) 增加:com/bj58/test/SizeOfAgent.java(读入= 3147) (写出= 1204)(压缩了 61%) 增加:com/bj58/test/Test$Person.class(读入= 442) (写出= 305)(压缩了 30%) 增加:com/bj58/test/Test.class(读入= 692) (写出= 441)(压缩了 36%) 增加:com/bj58/test/Test.java(读入= 509) (写出= 290)(压缩了 43%) D:\workspace\objsize\src>java -javaagent:size.jar com.bj58.test.Test 24 MANIFEST.MF: Manifest-Version: 1.0 Main-Class: com.bj58.test.Test Premain-Class: com.bj58.test.SizeOfAgent Boot-Class-Path: Can-Redefine-Classes: false 【注意】MANIFEST.MF文件的格式要求比较严格,每一行要满足:key:空格value回车 如何在web应用程序里面使用呢?
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
...先讲女主的灵魂飘荡了一段时间,然后重生,请问是那本? 拯救者散热器怎么开 电脑如何一键还原系统电脑一键还原怎么操作 神舟笔记本电脑怎么重新设置神舟战神bios恢复出厂设置 神舟电脑恢复出厂设置神舟战神怎么恢复原厂系统 水泥楼梯如何铺木楼梯 家里面楼梯是水泥的不想铺地毯或者地砖还能铺什么 楼梯的水泥台阶上可以铺地板革吗 手机腾讯会议共享屏幕播放视频没声 腾讯会议共享屏幕没声音怎么办 怎样才能得到央行发行的面额50元的开国大典纪念钞 正大(襄阳)现代农业投资有限公司怎么样? 凤冈县农业投资发展有限公司怎么样? 桐梓县农业投资有限责任公司怎么样? 农业生物科技公司的经营范围 的名称变成吃鸡专用号是怎么回事? 吃鸡游戏可以换绑定吗? 地级农业发展投资公司经营范围有哪些? 农业投资公司的经营范围有哪些 网名怎么改 吃鸡两个怎么换? 烧烤有什么新的酱料吗? 酱油米酒秘制鸡怎么做 微信怎样修改自己的名字和 酒坊如何做酱香米酒。需要什么材料。一步一步告诉我有奖。 自酿的米酒已经呈酱色能喝吗? 炖出来的排骨是苦的怎么办 陆夫人的b站头像是谁啦 米酒酱汁焖鸡腿的做法步骤图,怎么做好吃 求几篇英语短文或诗歌,笑话也行 JAVA的运行内存怎么看 如何看一段JAVA代码耗了多少内存 如何查看java线程占用的内存 实体店花呗使用支付? 查看java对象占堆内存多少个字节 java 获得当前系统内存 实体店怎么开通蚂蚁花呗收款 周深翻唱歌曲唱出新的感觉,这位歌手实力如何? 英国歌手唱周深的《大鱼》,歌手们互相翻唱的例子都有哪些? 周深《大鱼》被外国歌手翻唱,两人的唱法有何区别? 英国歌手翻唱周深的《大鱼》,你觉得好听吗? 周深京腔献唱紫禁城《光亮》MV出炉,他的歌唱功底究竟有多牛? 股票里几点不能撤单? 客厅不大,买哪种智能电视机较好? 求答案:恵州市惠阳区初中排名? 去惠阳一中能免学费,去惠州一中不能,我该选择哪所 客厅电视什么品牌好? 惠阳一中近五年录取分数线 惠州市2010中考成绩 怎么看待惠阳第五中学?