字符串是有問題的
基本上在Java中,String
引用(使用char[]
幕後的東西)將智慧主宰最業務應用程序的內存。它們的創建方式決定了它們在JVM中佔用的內存量。
僅僅因爲它們對於大多數業務應用程序來說如同數據類型一樣非常重要,並且它們也是最需要內存的之一。這不僅僅是一個Java事物,String
數據類型在幾乎每種語言和運行時庫中佔用大量內存,因爲至少它們只是每個字符1個字節的數組,或者更糟糕的是(Unicode),它們是數組每個字符多個字節。
一旦紋上的Web應用程序,也有一個Oracle JDBC的依賴CPU的使用率,當我發現StringBuffer.append()
由多個數量級的占主導地位的CPU週期比所有其他方法調用結合,更不用說其他任何單一的方法調用。 JDBC驅動程序做了大量的操作,使用PreparedStatements
來處理所有事情。
你是什麼人關心你無法控制,不能直接反正
你應該專注於什麼是什麼在你的控制,這是確保你不抱上引用長於你需要,而且你沒有不必要的重複。 Java中的垃圾收集例程經過高度優化,如果您瞭解它們的算法如何工作,則可以確保您的程序以最佳方式運行這些算法。
Java堆內存不喜歡手動管理存儲在其他語言中,這些規則並不適用
什麼被認爲內存泄漏其他語言是不一樣的東西/根源爲用Java的垃圾收集系統。
最有可能在Java內存中沒有被泄漏的單個超級對象(其他環境中的懸掛參考)佔用。
這是最有可能的,因爲很多StringBuffer
/StringBuilder
對象不是第一instantantations適當大小,然後不得不自動增長char[]
陣列舉行後續append()
通話較小的分配的。
由於垃圾收集器的範圍和許多其他事情在運行時可能會有所不同,因此這些中間對象可能比垃圾收集器預期的時間長。
示例:垃圾收集器可能會決定有候選人,但由於它認爲仍有大量內存需要處理,因此在該時間點刷新它們可能太昂貴了,它會一直等到內存壓力升高。
垃圾收集器現在真的很好,但它不是魔術,如果你正在做退化的事情,它會導致它不能最佳工作。互聯網上有大量關於所有JVM版本的垃圾收集器設置的文檔。
這些未引用的對象可能尚未達到垃圾回收器認爲需要它們從內存中清除它們的時間,或者可能存在其他對象(例如List
)所引用的引用你沒有意識到仍然指向那個對象。這在Java中最常被稱爲泄漏,這是更具體的參考泄漏。
例:如果你知道你需要使用StringBuilder
與new StringBuilder(4096);
不是默認的,這就好比32,並立即開始創建的垃圾,可以代表很多時候你在想什麼對象應該創造它來建立一個4K String
在尺寸上明智。
你可以發現有多少類型的對象用VisualVM實例化,這會告訴你你需要知道什麼。不會有閃光燈指向一個類的單個實例,即「這是大內存消費者!」,即除非您正在閱讀的某個char[]
只有一個實例大量的文件到,這也是不可能的,因爲很多其他類在內部使用char[]
;然後你幾乎已經知道了。
我沒有看到OutOfMemoryError
任何提及,你可能沒有在你的代碼中的問題,垃圾收集系統,只是可能沒有得到足夠的壓力下踢在和釋放放置物體你認爲它應該清理。什麼你認爲是一個問題可能不是,除非你的程序崩潰與OutOfMemoryError
。這不是C,C++,Objective-C或任何其他手動內存管理語言/運行庫。你不能決定什麼是在記憶中,或者不在你所期待的細節層面上。
我使用了一個分析器,它可以顯示我分配對象的位置。我不知道VisualVM是否可以做到這一點,但它非常有用。我使用的是YourKit,但它不是免費的(但你可以獲得一個eval許可證) – 2012-04-11 15:31:40
@PeterLawrey我實際上閱讀了你前面寫過的一個答案,你提到yourkit是你的第一選擇,我確實查了它(因爲你的建議總是很棒),但是它有點貴,我只是在學習。 – 2012-04-11 15:33:50
沒有使用儀器代碼的東西沒有分析儀將能夠指出哪個實例==你稱爲你的來源參考。 – 2012-04-11 16:05:04