2012-04-16 98 views
10

我有一個KDB/Q數據庫,每天大約有約2百萬條記錄消耗約2G內存。在一天結束時,它會運行一些報表,在表格之間進行連接並將結果輸出到磁盤上的文件中。在計算過程中,內存使用量增長到〜15G。我的問題是,一旦這個操作完成,內存永遠不會被釋放回來,直到數據庫重新啓動,它將消耗所有15G的內存。KDB/Q內存消耗

我想告訴KDB從內存中卸載某些表(不把它們雖然),但我不希望重新啓動數據庫,因爲一些其他應用程序仍然連接到它。

有沒有辦法告訴KDB卸載內存中的東西?

編輯:

如果有人發現它很有趣,我建議有KDB 2.5+上.Q.gc[]一看,看起來很有希望。

回答

7

下面是總結我的研究:

  • KDB爲版本之前。 2.5根據需要分配64MB內存塊,從不釋放它們。它能夠重用它們。
  • 最近KDB版本允許.Q.gc[]通話這是對請求調用垃圾收集器(KDB使用參考。順便說一句計數。)
  • 當你調用一些內存密集型計算其分配大量內存(在我的情況下,這是非常有用的它是〜20gB)並且您想在計算完成後釋放內存。
  • 你總是可以考慮將內存密集型腳本到一個單獨的Q的處理,因此內存將被釋放,一旦腳本完成
4

這可能是顯而易見的,但除了檢查您的版本垃圾收集模式的q,確保你確實已經擺脫了使用內存的內存數據。如果你確定與擺脫整個表格的(例如,這是參與計算的臨時表),剛剛從根命名空間中刪除

delete table from`. 

如果沒有,你可以刪除其所有行

delete from`table 
2

對於任何人在未來的最簡單的方法嘗試,這將一直到:

  1. 啓動一個新的KDB過程。
  2. 從這一過程查詢來選擇出所需要的數據的最小有限子集。
  3. 執行連接/計算/寫從過程到文件。 (允許原進行處理的請求)
  4. 關閉的過程中,釋放所有的內存。

正如上述海報所提到的,KDB的新版本釋放內存更好但不完美。

有我們公司的網站一個很好的文章,詳細介紹KDB +內存管理: http://timestored.com/kdbGuides/memoryManagement

1

http://code.kx.com/q4m3/12_Workspace_Organization/#125-expunging-from-a-context

我用了幾個不同的命令。只要您的表格在清除之前存儲在磁盤上,您應該沒問題。

這是創建表之前的會話。

q).Q.w[] 
used| 290192 
heap| 67108864 
peak| 67108864 
wmax| 0 
mmap| 0 
mphy| 8589934592 
syms| 629 
symw| 20704 

此命令創建表並將其保存到磁盤。

q)t:([]10000?"ab"; 10000?5) 
q)save `t 
`:t 

表仍然在內存

q).Q.w[] 
used| 437808 
heap| 67108864 
peak| 67108864 
wmax| 0 
mmap| 0 
mphy| 8589934592 
syms| 629 
symw| 20704 

讓我們從內存和垃圾抹去變量收集。

q)delete t from `. 
`. 
q).Q.gc[] 
0 

現在使用的內存已經減少到與會話開始相似的數量。

q).Q.w[] 
used| 290208 
heap| 67108864 
peak| 67108864 
wmax| 0 
mmap| 0 
mphy| 8589934592 
syms| 630 
symw| 20730 
q)\v 
`symbol$()