2009-12-02 40 views
1

我有一張大約20列的表,主要由varchars和小數組成。這張桌子有近150萬行。但是他們中很少有東西是常見的,比如column1只包含100個不同的字符串,column2幾乎有1000個,而column3有近500個。如何通過在Java中壓縮我的對象來減少總內存佔用率?

現在,我將所有這些列值存儲在Key中作爲前5列,數據作爲其餘列。我的任務是這樣的,我需要在任務開始時初始化所有這些。

我應該使用什麼模式(如Flyweight等)或數據結構來最小化我的對象存儲?

爲什麼我需要預加載所有數據?

假設表格的全部數據爲樹,受害者可以位於任何葉,樹幹或根目錄。因此,對於每個條目[這是來自不同的地方],我需要看看樹中是否有任何匹配。

回答

2

內化不是最好的選擇。垃圾收集從PermSpace是可能的,但虛擬機沒有優化。

您可以實現自己的CharSequence實現由共享char []數組支持。

通過CharSequence實現,您將能夠實現基本的共享語義,如內化字符串或更復雜的子字符串和其他投影。

定製CharSequence的實施還可以優化到執行較少的內存分配比被複制的char []周圍的String類(出於安全原因,是沒有必要的,如果你有後盾的char []您的完全控制之下)。即使new String("..").intern()也會實例化一個新的String實例(char []數組),該實例被快速垃圾收集。

+0

你的意思是http://java.sun.com/j2se/1.5.0/docs/api/java/lang/CharSequence.html,但這將如何幫助我的案例 – DKSRathore 2009-12-02 13:43:39

+0

如果你可以自由地用CharSequence替換String在你的上下文中,你可以有一個自定義的實現,比通用的String實現更好地執行。 – 2009-12-02 13:49:30

+0

我認爲這可能有幫助,但無法實現這一點。你可以提供一些實現或一些好的鏈接的細節? – DKSRathore 2009-12-02 13:55:08

1

我的第一個問題是,你有什麼計劃與表中的數據做什麼?將完整的表格預加載到內存中並不總是最好的方法,例如保持當前的設置,但按需加載可能是更好的解決方案。您可能需要調查一段時間內未使用的刷新數據,即某種最近使用過的地圖。

您能詳細說明一下您的任務試圖通過緩存在地圖中的所有數據來實現嗎?

「受害者」是對象的關鍵部分還是對象的一部分?如果對象的一部分,你如何選擇選擇你需要的對象的鍵?換一種說法;這聽起來像你試圖重現數據庫非常擅長的功能。

如果您的問題在於您的表格內容無法在樹形結構上輕鬆映射,則可以通過數據庫接口以可用方式添加該信息。

+0

RSp,我在問題中加入了這個。 – DKSRathore 2009-12-02 13:58:47

0

如果您的數據加載過程可以支持它,那麼實現類似String.intern()而沒有GC permgen副作用並不難。

對於任何可排列的數據元素,可以簡單地使用Map<T,T>來查找預先存在的實例。所以對於字符串:

Map<String,String> stringCache = new HashMap<String,String>(); 
... 
String sharedValue = stringCache.get(loadedValue); 

加載來自任何地方的數據仍將創建臨時字符串,但這些將快速GC'ed的過程。在不瞭解數據來源的具體細節的情況下,很難評論這些臨時對象是否有必要,儘管我很難看到它。無論如何,它們將在裝載過程中迅速回收。

相關問題