posts - 37, comments - 9, trackbacks - 0, articles - 0

          計算機java對象占用的內存

          Posted on 2006-04-22 21:25 飛翔 閱讀(147) 評論(0)  編輯  收藏

          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 (), 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()可以幫我們真正的確定完成垃圾收集(準確的說,應該說是基本上完成)。

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 句容市| 桐庐县| 奎屯市| 上饶县| 丰镇市| 华宁县| 石棉县| 仁化县| 毕节市| 普安县| 黔南| 新疆| 乐清市| 宣武区| 天台县| 延边| 如东县| 秭归县| 隆子县| 基隆市| 社会| 兴文县| 波密县| 弋阳县| 肥乡县| 筠连县| 两当县| 通海县| 安化县| 龙江县| 元阳县| 辽宁省| 新沂市| 松桃| 汕头市| 威宁| 昔阳县| 自治县| 南通市| 衡东县| 永年县|