你知道資料大小嗎?--不要花太多的功夫來隱藏類的成員(一) (轉)
你知道資料大小嗎?:namespace prefix = o ns = "urn:schemas--com::office" />
--不要花太多的功夫來隱藏類的成員
摘要:
過去很多年裡面,許多的開發人員都一直在問一個問題:“一個Java到底耗費多少呢?”在本文中,Vladimir Roubtsov用以前的解決方案來解釋了這個問題,在此之外,基於他的演示了記憶體的使用,並且還提供了一些技巧來讓你的Java更加高效。
作者:Vladimir Roubtsov
近來,我們幫助開發了一個Java,這是一個類似記憶體的應用。那就是說,我們特別強調設計,因為設計要特別考慮在記憶體中快取大量的資料來提高查詢的。
一旦我們得到執行的原型,那麼在資料從上宰入經過分析以後,我們自然的決定了資料的輪廓。不太滿意的初始效果,促使我們尋找更好的解決方案。
工具:
既然Java有目的的隱藏了很多記憶體管理的細節資訊,要發現你的物件要消耗多少記憶體的確要花一些功夫。你可以使用Runtime.freeMemory()方法來測量在一個或者多個物件被分配前前後的堆的變化值。有一些文章,例如(Ramchander Varadarajan's "/jw-javatip130.html#res#resources">Question of the Week No. 107" (Sun Microsystems, September 2000) and Tony Sintes's "" (JavaWorld, December 2001))都詳細地介紹了這些方法。但是不幸的是,這些先前的文章的解決方案的失敗在於實現中使用了一個錯誤的Runtime方法。即使後來的文章也有它的不完整性。
l Runtime.freeMemory() 方法提供的功能是不夠的,因為JVM可以在任何時候(只要需要,特別是在執行垃圾收集的時候)決定增加它的當前的堆大小。除非在執行的時候已經使用了引數-Xmx指定了堆的最大值,否則我們應該使用Runtime.totalMemory()-Runtime.freeMemory()作為在使用的堆大小。
l 單個Runtime.gc()方法並不能保證有效的請求垃圾收集。舉例來說,我們可以請求物件的finalizer執行正常。既然Runtime.gc()不能保證阻塞到垃圾處理,那麼一直等待到當堆大小穩定以後是一個很好的辦法。
l 如果輪廓類建立了一個靜態的資料作為先前的類初始化的一部分,那麼堆記憶體對於第一個類例項的分配的空間應該包括這個資料。我們應該忽略被第一個類例項消耗的堆空間。
考慮這些問題:我們給出了一個Sizeof,作為一個工具來檢視各種Java核心和應用類。
public class Sizeof
{
public static void main (String [] args) throws Exception
{
// Waup all classes/methods we will use
runGC ();
usedMemory ();
// Array to keep strong references to allocated s
final int count = 100000;
Object [] objects = new Object [count];
long heap1 = 0;
// Allocate count+1 objects, discard the first one
for (int i = -1; i < count; ++ i)
{
Object object = null;
// Instantiate your data here and assign it to object
object = new Object ();
//object = new Integer (i);
//object = new Long (i);
//object = new String ();
//object = new byte [128][1]
if (i >= 0)
objects [i] = object;
else
{
object = null; // Discard the warm up object
runGC ();
heap1 = usedMemory (); // Take a before heap snapshot
}
}
runGC ();
long heap2 = usedMemory (); // Take an after heap snapshot:
final int size = Math.round (((float)(heap2 - heap1))/count);
System.out.println ("'before' heap: " + heap1 +
", 'after' heap: " + heap2);
System.out.println ("heap delta: " + (heap2 - heap1) +
", {" + objects [0].getClass () + "} size = " + size + " bytes");
for (int i = 0; i < count; ++ i) objects [i] = null;
objects = null;
}
private static void runGC () throws Exception
{
// It helps to call Runtime.gc()
// using several method calls:
for (int r = 0; r < 4; ++ r) _runGC ();
}
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 ();
}
}
private static long usedMemory ()
{
return s_runtime.totalMemory () - s_runtime.freeMemory ();
}
private static final Runtime s_runtime = Runtime.getRuntime ();
} // End of class
Sizeof的關鍵方法是runGC() 和usedMemory()方法,我使用了runGC()這樣的封裝方法來呼叫_runGC()幾次,是為了讓這個方法有更加明顯的效果。
注意我呼叫runGC()方法的地方,你可以在heap1和heap2編輯你的程式碼,加入你任何你感興趣的例子。
也請注意Sizeof怎麼樣輸出物件的大小,資料的傳遞閉包要求被用所得count類例項所用到,然後被count整除。對於大多數類來說,這個結果將是單個類例項物件所耗費的記憶體大小,包括所有它自己的成員域。記憶體的界限值不同於由一些商業的工具報告的影子記憶體界限(比如說,如果一個物件有一個int[],那麼它的記憶體消耗將顯得很特別)。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752019/viewspace-957579/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 你知道資料大小嗎?--不要花太多的功夫來隱藏類的成員(三) (轉)
- 你知道資料大小嗎?--不要花太多的功夫來隱藏類的成員(二) (轉)
- 蘋果mac隱藏的神技能,你都知道嗎蘋果Mac
- 超好用的macOS Monterey 隱藏功能,這些你都知道嗎Mac
- 類成員函式的重寫,過載和隱藏的區別函式
- 隱藏的資料夾怎麼找出來 恢復隱藏資料夾的辦法
- ABAP Code Inspector那些隱藏的功能,您都知道嗎?
- Python中你所不知道的“隱藏技巧”!Python
- win10隱藏的資料夾怎麼找出來 顯示隱藏資料夾步驟Win10
- iOS 8的這十項隱藏功能 你都知道麼?iOS
- 你知道資料庫索引的工作原理嗎?資料庫索引
- 依據類的成員來對類進行排序的泛型方法 (轉)排序泛型
- 你可能不知道的 10 個 Laravel Eloquent 的隱藏特性Laravel
- 隱藏資料夾怎麼取消隱藏 關閉隱藏檔案的辦法
- 關於一些類病毒隱藏技術的設想 (轉)
- C++ 成員函式的過載,繼承,覆蓋和隱藏C++函式繼承
- EXCEL你不知道的三個秘密:沒想到隱藏的這麼深Excel
- 你可能不知道的10個CSS3中的隱藏特性CSSS3
- 資料隱藏技術資料隱藏
- iOS 9正式釋出,你發現其中隱藏的功能了嗎iOS
- 作為開發人員,這四類Code Review方法你都知道嗎?View
- 你知道MySQL是如何處理千萬級資料的嗎?MySql
- 推薦五款寶藏軟體,身為寶藏男孩和寶藏女孩的你,不試一下嗎?
- win10資料夾如何隱藏_win10系統的資料夾怎麼隱藏Win10
- 資料夾的隱藏(十)終極篇
- Notes隱藏資料庫設計應用的維護 (轉)資料庫
- CWinApp類成員 (轉)APP
- 移動端動態化的由來,你知道嗎?
- 你知道Ctrl+Alt+Delete是怎麼來的嗎?delete
- win10 如何顯示隱藏資料夾_win10 如何顯示隱藏的資料夾Win10
- win10如何顯示隱藏資料夾 win10開啟隱藏資料夾的方法Win10
- 這些著名資料庫之間的“關係”,你知道嗎?資料庫
- 你知道嗎?常用的資料探勘分析工具Mahout和MLlib
- win10怎樣顯示隱藏的資料夾_win10隱藏檔案怎麼顯示出來Win10
- 隱藏資料夾怎麼顯示出來win10 win10怎麼開啟隱藏的檔案Win10
- GRUB選單隱藏的解除(轉)
- 刪除WinXP隱藏的元件(轉)元件
- win10怎麼顯示隱藏資料夾 win10顯示隱藏資料夾的方法Win10