2013-03-16 78 views
1

我有一個靜態類,其中有一個方法,我跑了幾百次。目前,每次運行該方法時,都會創建兩個不同的堆棧對象。如果我要使該類非靜態,那麼我可以在構建時創建兩個堆棧,然後通過清除它們來重用它們,它會更快嗎?我想答案取決於創建一個新的堆棧對象vs清除現有的堆棧對象(無論如何都可能是空的),並且如果清除它的性能增益(如果有的話)大於非靜態方法的性能損失。Java的android優化。非靜態還是靜態方法?

我試着分析這兩個,它似乎從來沒有工作,但這是一個不同的問題。

+1

可以顯示代碼(至少是相關部分)嗎? – assylias 2013-03-16 14:19:09

+1

你有一個靜態方法的類(不是「靜態類」)嗎?你的意思是堆棧對象在調用堆棧上不是對象嗎? Java對象始終在堆上。 – 2013-03-16 15:43:22

+0

如果您只調用該方法幾百次(而不是每秒幾百次),則該方法是否爲靜態並不重要。 – Niels 2013-03-17 08:04:32

回答

2

這取決於你如何在代碼中使用靜態變量和方法。

實例變量和對象存儲在堆上。 局部變量存儲在堆棧中。

靜態變量存儲在堆上的永久區域中。垃圾收集器通過標記和清理對象來工作。加載類時,無法爲垃圾收集選擇靜態變量。當相應的類加載器(負責加載這個類)本身被收集用於垃圾時,可以收集它們。

如果我有一個值傳遞給另一個活動,我會使用意圖,而不是靜態變量。

在自定義列表適配器中,我們使用靜態視圖。所以使用靜態變量或方法取決於不同的情況。

您可以使用名爲MAT Analyzer的工具分析對象的內存使用情況。下面的視頻講述了內存管理以及如何檢測和解決內存泄漏問題

http://www.youtube.com/watch?v=_CruQY55HOk

MemoryInfo mi = new MemoryInfo();// current memory usage 
    ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE); 
    activityManager.getMemoryInfo(mi); 
    long availableMegs = mi.availMem/1048576L; 

http://developer.android.com/training/articles/perf-tips.html。看看這個鏈接的性能提示,特別是下的主題。首選靜態虛擬

內存可用性是要考慮使用靜態變量和性能方法並避免內存泄漏的標準之一。

+0

在我發佈之前,我在android.com上閱讀了該鏈接。它仍然沒有真正回答我的問題,因爲一方面它使用靜態方法,另一方面它說避免創建對象。如果我使該方法成爲靜態方法,那麼每次運行時都必須創建堆棧對象。如果方法是非靜態的,我可以重用堆棧對象。 – Joymo 2013-03-16 22:58:34

+0

你是否使用靜態變量獲取任何內存泄漏? – Raghunandan 2013-03-17 06:00:33

0

這實際上是一個關於嘗試重用對象的問題。如果聲明static成員,則也可以在static方法中重複使用對象。另外:是的,這可能是更好的設計這沒有static什麼。

無論如何,重用的好處是避免創建對象。您仍然需要支付一些「清除」對象狀態的開銷。否則,在類似Stack的情況下,您可能會冒內存泄漏。

存在一個持續的維護問題:您將新狀態添加到對象,並且您是否記得更新清除它的方法?

您還需要現在synchronize訪問此方法或以其他方式阻止兩個線程一次使用它。這可能會導致瓶頸,因爲線程無法同時執行該方法。

您還總是爲整個運行時支付此對象的內存成本。

在過去,人們會創建對象池抽象以避免重新創建對象。這有其自身的複雜性和運行時間的開銷,並且通常很不受歡迎,因爲創建對象和GC的成本現在非常小。

試圖重新使用對象僅用於性能很少是性能上的勝利。它必須處於一個緊密的循環中,並且不會遇到以上幾個可能的問題值得。