2012-12-02 51 views
1

據我所知,在老一代JVM的空間,它可以被用於兩個目的,老一代空間utlization在JVM

  1. 用於從年輕一代提升到老一代對象?
  2. 特殊用例(https://stackoverflow.com/questions/9053144/will-i-encounter-java-lang-outofmemoryerror-even-with-no-lack-of-memory

我的問題是用於新對象分配,

  1. 是否有任何其他用途的情況下,其將利用在老一代的空間?
  2. 我認爲有一個內存拷貝涉及到從年輕一代複製對象到老一代,它是一個深拷貝還是一個淺拷貝?

在此先感謝, 林

+0

是你的記憶顯示持續增加?你使用任何靜態地圖或其他東西? –

+0

嗨@Narendra,我想搞清楚GC的一些基本知識,因爲我可能需要調整寫入重度應用程序。 –

+0

好的。因爲內存泄漏導致老一代的不斷增加。這就是爲什麼這樣的問題 –

回答

1

我來回答2.它絕對不是一個深複製:GC處理的對象爲不同的內存塊和深度複製真的只意味着複製是連接許多不同的對象到一個對象圖中。另外,你最好想象一下移動,而不是副本;複製實際上只是一個「實施細節」,所需的效果正在重新定位。

+0

謝謝@Marko,是的,我同意使用移動是一個更好的選擇。其實我的問題是,1.它真的是整體移動,或者只是移動一個參考。例如,有一個對象,它是一個包含1M個字符的緩衝區,當將年輕代中的緩衝區對象提升爲舊代時,我們移動整個1M個字符,2.假設存在一個提升的對象,我們是否將它的整體對象圖(即使圖上的某些對象不符合升級條件)?如果不是,GC會在對象圖中處理修復對象引用更新問題? –

+0

在考慮GC時只是忘記封裝。它將rbuffer對象視爲一個小結構,並將1M數組視爲一個單獨的塊。他們完全相互獨立。請注意,無論您移動對象圖還是僅移動根對象,修正指針始終是一項要求。指針不是相對的。是的,整個陣列在推廣到Tenured世代時將會被重新定位(複製),除非它是如此巨大,以至於它在一開始就被正確分配。 –

+0

感謝詳細deply,@Marko。讓我通過重複我的理解來確認我的理解是正確的,1.引用/指針由GC固定2. GC將獨立處理每個對象(提升或移動),而不是將對象圖作爲一個整體來促進(或移動)? –

1

在他的評論中放置該代碼在回答這個問題的@Lin馬:

class SomeClass{ 
    private static List<Object> memoryLeakCulprit = new ArrayList<Object>(); 



    void someMethod(Object obj){ 

      //adding the reference of some object in the culprit list 
      memoryLeakCulprit.add(obj); 

    } 

    //supposed to remove the reference passed 
    void someOtherMethod(Object obj){ 

     obj = null; 

     //bummer forgot to remove the reference from list 

     //now the instance is not reachable by obj 
     //so now as new references are added to culprit list the memory will keep on increasing in size 

    } 

} 

UDPATE

如何解決此泄漏

oid someOtherMethod(Object obj){ 

       //before setting the obj reference to null it must be removed from culprit list 
       memoryLeakCulprit.remove(obj); 

       //now its safe to set this reference to null 
       obj = null; 

     } 

只有這樣,才能解決泄漏到配置文件使用一些性能分析工具的應用程序,如JProfiler,VisualVM並找出哪些類導致泄漏。

當您找到課程該代碼將需要更改,這是唯一的方法。

還有在程序退出之前不需要釋放引用。原因是static變量(memoryLeakCulprit)綁定到對象,並且只要您退出程序,所有引用都會自動釋放,包括類對象。

關於其他說明,請務必在退出程序之前關閉系統資源(套接字,數據庫連接)。

+0

嗨@Narendra,我認爲在你的示例中,對象是由memoryLeakCulprit引用的,所以對象不是GCed?我認爲預計該對象不是GCed,當有任何引用時,爲什麼你認爲有泄漏?謝謝。 –

+0

@LinMa我認爲你是誤解泄漏,這是一個編程錯誤,被認爲發生了很多次。就像這裏它只是一個小程序一樣,很容易識別。但是,當有1000K LOC時,它並不那麼容易。這就是爲什麼人們使用堆轉儲和JConsole類型的應用程序來查找泄漏。這是一個編程錯誤! –

+1

引用維基百科:計算機科學中的內存泄漏(或泄漏)在計算機程序獲取內存但未能將其釋放回操作系統時發生[1]。在面向對象編程中,當對象存儲在內存中但運行代碼無法訪問時,可能會發生內存泄漏。 –