`

计算java对象占用的内存

 
阅读更多

Java有一个很好的地方就是java的垃圾收集机制,这个机制集成于jvm的,对程序员来说是隐藏且不透明的。这种情况下,如何得到某个对象消耗的内存呢?
  
曾经看到过有人用以下方法来计算:在生成该object的前后都调用java.lang.Runtime.freeMemory()方法,然后看两者之差即为该object消耗的内存量。
  
这种方法的代码是:

long totalMem = java.lang.Runtime.freeMemory();
Object myBigObject = null;
System.out.println("You just got rid of " + totalMem - java.lang.Runtime.freeMemory());

   
这种想法是对的,但是实际上,jvm的freememory往往不能正确反应实际的free memory。比如在jvm要进行垃圾收集的时候,free memory就会缩小。而如果决定垃圾收集的时间发生在该object生成之后,而在第二次调用java.lang.Runtime.freeMemory()之前,那么就会错误地增加该object消耗的内存量。

在java专家By Tony Sintes的文章"Discover how much memory an object consumes " 里面提到了应该用Runtime.getRuntime().totalMemory();并且计算两次之差来得到消耗的内存量。

By Tony Sintes的源代码:

public class Memory {
   private final static int _SIZE = 500;
   public static void main( String [] args ) 
   throws Exception {
   Object[] array = new Object[_SIZE];
   Runtime.getRuntime().gc();
   long start = Runtime.getRuntime().totalMemory();
   for (int i = 0; i < _SIZE; i++) {
   array[i] = new Object();
   }
   Runtime.getRuntime().gc();
   long end = Runtime.getRuntime().totalMemory();
   long difference = ( start - end ) / _SIZE;
   System.out.println( difference + " bytes used
  per object on average" );
   }
}

   
实际上,这种方法基本上正确了,但是By Tony Sintes疏忽了一点,就是仅仅Runtime.getRuntime().gc();并不能真正完成垃圾收集,也就是说实际上jvm的内存此时并不是稳定的。 所以,只有当内存不再发生大的变动,或者说已经稳定,我们才可能说垃圾收集已经完成。如何才能真正确保基本完成了jvm的垃圾收集呢?实现这个功能的代码如下:

private static final Runtime s_runtime = Runtime.getRuntime ();
  private static long usedMemory (){
   return s_runtime.totalMemory () - 
   s_runtime.freeMemory ();
  }

  private static void runGC () throws Exception{
    long usedMem1 = usedMemory ();
         long usedMem2 = Long.MAX_value;
    for (int i = 0; (usedMem1 < usedMem2) && (i < 500); ++ i){
     s_runtime.runFinalization ();
     s_runtime.gc ();
     Thread.currentThread ().yield ();
     usedMem2 = usedMem1;
     usedMem1 = usedMemory ();
   }
}

 

runGC()可以帮我们真正的确定完成垃圾收集(准确的说,应该说是基本上完成)。

分享到:
评论

相关推荐

    JAVA对象所占内存大小计算例子

    本文将深入探讨如何计算Java对象所占内存,并通过提供的代码示例进行详细解析。 首先,我们需要理解Java对象内存占用的基本原理。每个Java对象都由三部分组成:对象头(Object Header)、实例数据(Instance Data)...

    计算一个Java对象占用字节数的方法

    本篇文章将深入探讨如何计算Java对象占用的内存字节数,以及影响这一数值的因素。 首先,Java对象在堆内存中由四个部分组成:对象头(A)、基本类型域(B)、引用类型域(C)和填充物(D)。 **对象头(A)**: ...

    统计缓存(java对象所占的内存)大小

    本文将深入探讨如何统计缓存(尤其是Java对象)所占的内存大小,以及这对理解程序内存消耗的重要性。 首先,我们要知道Java对象的内存开销主要由三部分组成:对象头、实例数据和对齐填充。对象头包含对象的类型信息...

    测试java对象占用内存大小的例子

    本示例主要探讨如何测试Java对象占用的内存大小,以便更好地理解内存使用情况。 首先,`SizeOf.java`可能是一个实现自定义内存大小计算的类。在Java中,由于垃圾回收机制的存在,直接获取对象的内存占用并不像C++等...

    计算java对象大小

    这篇博客文章可能探讨了如何通过不同的工具和技术来估算Java对象在内存中的占用空间。 首先,Java对象的大小不是固定不变的,它取决于对象的类结构,包括类中的属性数量、类型以及虚拟机的实现。每个对象都会有一个...

    java-sizeof-0.0.4:一个查看java对象占用内存大小

    了解对象占用的内存大小有助于我们优化资源使用,减少内存泄漏,并提高程序效率。 "java-sizeof-0.0.4"是一个用于分析Java对象内存占用的工具,它可以帮助开发者更好地理解对象在运行时的内存消耗。这个工具提供了...

    java字符串内存计算

    接下来,我们将详细介绍如何精确地计算Java字符串所占用的内存空间。这里主要关注字符串对象本身的内存占用情况,而非其引用部分。 ##### Java字符串结构分析 在Java中,字符串(String)是一个不可变的对象,它主要...

    计算java对象的大小的方法

    本文将深入探讨如何计算Java对象的大小,以及这个知识点在实际开发中的应用。 首先,Java对象的大小不仅仅包括其字段的大小,还包括对象头(object header)的大小,对于HotSpot虚拟机,它包含了对齐填充、Mark ...

    计算对象占用内存空间ObjectSize-master.zip

    "计算对象占用内存空间ObjectSize-master.zip" 提供的工具可能是一个帮助开发者分析和估算对象在内存中占用大小的解决方案。这样的工具对于调试、性能调优以及避免内存泄漏至关重要。 在Java中,对象的内存占用不...

    Java占用内存的研究.pdf

    一个空的String对象占用28个字节的内存,包含了一个指向字符数组的引用、一个偏移量、一个字符的长度和一个哈希码。当字符串内容非空时,内存占用会增加,因为需要存储字符数据。例如,字符串"ab"会占用28 + 2 * 2 =...

    java 通过sizeOf计算一个对象的大小

    总的来说,通过`sizeOf`计算Java对象的大小是一项复杂的工作,涉及到JVM内部的内存管理和对象表示。尽管Java API没有直接提供这样的功能,但我们可以借助第三方库或自定义工具来实现。理解对象大小对于优化内存使用...

    JAVA技巧(Java多线程运行时,减少内存占用量).pdf

    本文介绍了在Java多线程环境下减少内存占用量的一些关键策略,包括线程生命周期管理、对象生命周期设计、同步机制选择、线程池的使用和线程数量控制。同时,代码的异常处理和JVM参数调优也是提升多线程应用性能的...

    Java 对象(数组)占多大空间(几个字节) 手把手做实验

    总之,Java对象和数组的内存占用取决于JVM的配置、对象的字段、数组的元素类型和长度等因素。开启或关闭压缩选项会影响对象和数组引用的大小,进而影响整体的内存占用。对于内存优化和性能调优来说,了解这些细节至...

    为什么Java程序占用的内存比实际分配的多

    Java程序在运行过程中占用的内存通常比通过-Xmx和-Xms参数所设定的堆内存大小要多,这是由于Java程序的内存消耗不仅限于堆内存。以下是对各个影响因素的详细解析: 1. **对象(Objects)**:这是Java程序中最基本的...

    java实现内存动态分配

    Java的垃圾回收机制(Garbage Collection, GC)负责自动回收不再使用的对象所占用的堆内存。当一个对象不再有引用指向它时,该对象成为垃圾,GC会在适当的时候将其回收,释放内存。在实验中,虽然没有直接涉及垃圾...

    完美解决java读取excel内存溢出问题.rar

    6. **延迟加载和只读模式**:如果只需要读取Excel文件,可以选择只读模式,这将减少内存占用。同时,某些数据的加载可以等到需要时再进行,即延迟加载。 通过这些方法,我们可以有效地处理大Excel文件,避免Java...

    测量Java对象大小的demo

    本示例“测量Java对象大小的demo”提供了一种方法,通过使用Java的`java.lang.instrument`包来注入`javaagent`,进而利用`Instrumentation`接口测量Java对象的精确内存占用。下面我们将详细探讨这一过程。 首先,`...

    java内存分配 内存泄漏

    Java中,内存泄漏通常是因为引用了不再使用的对象,使得垃圾收集器(Garbage Collector)无法回收这些对象占用的内存。 JVM的内存管理机制包括垃圾收集,它自动回收不再使用的对象内存。垃圾收集器通过可达性分析...

    如何计算Java对象占用了多少空间?

    这里我们将深入探讨计算Java对象占用空间的方法。 首先,每个Java对象都包含一个对象头(Object Header),它存储了一些元数据信息。对象头通常由两部分组成: 1. **Mark Word**: 这部分存储了对象的哈希码、锁...

Global site tag (gtag.js) - Google Analytics