java语言如何得到当前java内存对象大小中的所有对象

Java复习题(二)填空题答案_百度文库
您的浏览器Javascript被禁用,需开启后体验完整功能,
享专业文档下载特权
&赠共享文档下载特权
&100W篇文档免费专享
&每天抽奖多种福利
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
Java复习题(二)填空题答案
阅读已结束,下载本文需要
定制HR最喜欢的简历
下载文档到电脑,同时保存到云知识,更方便管理
加入VIP
还剩6页未读,
定制HR最喜欢的简历
你可能喜欢百度题库旨在为考生提供高效的智能备考服务,全面覆盖中小学财会类、建筑工程、职业资格、医卫类、计算机类等领域。拥有优质丰富的学习资料和备考全阶段的高效服务,助您不断前行!
京ICP证号&&
京网文[3号&&
Copyright (C) 2018 Baidu如何查看java对象所占的内存大小
我们为什么想要知道对象所占对内存的大小呢?
(1)做一些cache的时候,我们不可能把的所有的数据都缓存到内存里面,我们要估计缓存的大小。
(2)内存泄露的时候,我们可以查看某些对象的大小来定位问题,当然还有其他的更有效的方式,比如使用MAT分析dump文件
(3)根据jvm的堆内存设置,我们可以知道最多可以创建多少个对象。
从jdk5开始,提供了Instrumentation API,它有一个叫做getObjectSize()的方法,但是,这个方法存在两个问题:
(1)不可以直接使用。必须要实现一个Instrumentation Agent,还得放到jar包里面。
(2)它只能返回单个对象的大小,不能返回内部包含的子对象的大小。
关于第一个问题,很好解决,在任何一个类里面声明一个&premain&方法,就可以把这个类做成是一个agent:
public class SizeOfAgent {
&&&&&&&& static I
&&&&&&&& /** initializes agent */
&&&&&&&& public static void premain(String agentArgs, Instrumentation instP) {
&&&&&&&&&&&&&&&& inst = instP;&&&&&&&&&&
&&&&&&&& }
jvm在启动的时候会调用premain()方法,同时会传递Instrumentation这个对象实例,要告诉jvm Instrumentation agent所在的类,需要把这个类打到jar包里面,
然后在manifest.mf这个文件设置一些属性:
Premain-Class: sizeof.agent.SizeOfAgent
Boot-Class-Path:
Can-Redefine-Classes: false
java应用在启动的时候,指定-javaagent参数:
java -javaagent:sizeofag.jar &Your main class&
拿到Instrumentation这个实例以后,就可以调用sizeOf()方法了:
public class SizeOfAgent {
&&&&&&&& static I
&&&&&&&& // ...
&&&&&&&& public static long sizeOf(Object o) {
&&&&&&&&&&&&&&&& return inst.getObjectSize(o);
&&&&&&&& }
然后可以使用反射来获取子对象的大小。
完整的代码如下:
package com.bj58.
import java.lang.instrument.I
import java.lang.reflect.A
import java.lang.reflect.F
import java.lang.reflect.M
import java.util.IdentityHashM
import java.util.M
import java.util.S
public class SizeOfAgent {
&&& static I
&&& /** 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();
&&& private static boolean skipObject(Object obj, Map&Object, Object& visited) {
&&&&&&& if (obj instanceof String) {
&&&&&&&&&&& // skip interned string
&&&&&&&&&&& if (obj == ((String) obj).intern()) {
&&&&&&&&&&&&&&&
&&&&&&&&&&& }
&&&&&&& 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 & i++) {
&&&&&&&&&&&&&&&&&&& stack.add(Array.get(obj, i));
&&&&&&&&&&&&&&& }
&&&&&&&&&&& }
&&&&&&&&&&&
&&&&&&& // process all fields of the object
&&&&&&& while (clazz != null) {
&&&&&&&&&&& Field[] fields = clazz.getDeclaredFields();
&&&&&&&&&&& for (int i = 0; i & fields. i++) {
&&&&&&&&&&&&&&& if (!Modifier.isStatic(fields[i].getModifiers())) {
&&&&&&&&&&&&&&&&&&& if (fields[i].getType().isPrimitive()) {
&&&&&&&&&&&&&&&&&&&&&&& // 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) {
&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&& }
&&&&&&&&&&&&&&&&&&& }
&&&&&&&&&&&&&&& }
&&&&&&&&&&& }
&&&&&&&&&&& clazz = clazz.getSuperclass();
然后我们可以做一个测试:
public class Test {
&&& static class Person{
&&&&&&& private S
&&&&&&& private S
&&&&&&& public Person(int id, String name, String address) {
&&&&&&&&&&& this.id =
&&&&&&&&&&& this.name =
&&&&&&&&&&& this.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&
(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
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应用程序里面使用呢?
以我的tomcat为例,
(1)把size.jar上传tomcat的lib目录下面
(2)修改catalina.sh:
添加一行:
JAVA_OPTS=&$JAVA_OPTS -javaagent:$CATALINA_HOME/lib/size.jar&& //这一行是新添加的
if [ -z &$LOGGING_MANAGER& ]; then
& JAVA_OPTS=&$JAVA_OPTS -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager&
& JAVA_OPTS=&$JAVA_OPTS $LOGGING_MANAGER&
(3)在应用里面添加一个controler:
@Path(value = &/api/size&)
public ActionResult size() {
&&& Map&Long, List&Long&& map = ApiUtils.getHotindexBaidu();
&&& long size = SizeOfAgent.fullSizeOf(map);
&&& return new ApiActionResult(&size:&+size);
然后就可以用来访问了。Java中如何查看一个引用类型的内存地址? - 知乎有问题,上知乎。知乎作为中文互联网最大的知识分享平台,以「知识连接一切」为愿景,致力于构建一个人人都可以便捷接入的知识分享网络,让人们便捷地与世界分享知识、经验和见解,发现更大的世界。5被浏览<strong class="NumberBoard-itemValue" title="分享邀请回答public static BigInteger valueOf(long val) {
// If -MAX_CONSTANT & val & MAX_CONSTANT, return stashed constant
if (val == 0)
return ZERO;
if (val & 0 && val &= MAX_CONSTANT)
return posConst[(int) val];
else if (val & 0 && val &= -MAX_CONSTANT)
return negConst[(int) -val];
return new BigInteger(val);
可以看到,当传入的参数为0时,直接返回的就是BigInteger.ZERO,它们能不相等吗?赞同 2 条评论分享收藏感谢收起写回答

我要回帖

更多关于 java对象占用内存大小 的文章

 

随机推荐