![](/img/trans.png)
[英]How can I avoid OutOfMemoryErrors when using Commons FileUpload's DiskFileItem to upload large files?
[英]How can I avoid OutOfMemoryErrors when updating documents in a Lucene index?
我正在嘗試以增量方式刷新Lucene索引,該索引用於更新已更改的文檔並保持其他未更改的文檔不變。
為了更新更改的文檔,我使用IndexWriter.deleteDocuments(Query)
刪除這些文檔,然后使用IndexWriter.addDocument()
添加更新的文檔。
IndexWriter.deleteDocuments
中使用的Query
對象包含大約12-15個術語。 在刷新索引的過程中,有時我還需要執行完全刷新,方法是使用IndexWriter.deleteDocuments
刪除所有文檔,然后添加新文檔。
問題是當我說刪除大約100000個文檔后調用IndexWriter.flush()
時,執行時間很長,並拋出OutOfMemoryError
。 如果我禁用刷新功能,索引會快速上升到說2000000 docs刪除,然后拋出OutOfMemoryError
。 我試圖將IndexWriter.setRAMBufferSizeMB
設置為500,以避免出現內存不足錯誤,但是沒有運氣。 索引大小為1.8 GB。
第一 。 增加RAM緩沖區不是您的解決方案。 據我了解,這是一個緩存,我寧願說這正在加劇您的問題。 OutOfMemoryError是JVM問題,不是Lucene問題。 您可以將RAM緩沖區設置為1TB-如果您的VM沒有足夠的內存,則仍然存在問題。 因此,您可以做兩件事:增加JVM內存或減少消耗。
第二 。 您是否已經考慮過增加堆內存設置? 永久清除的原因是系統在內存耗盡之前不久就進行了大量垃圾回收。 這是典型症狀。 您可以使用jvisualvm
類的工具進行jvisualvm
。 您需要先安裝GC詳細信息插件,然后才能選擇並監視瘋狂的OutOfMemory應用程序。 如果您了解內存問題,則可以增加最大堆空間,如下所示:
java -Xmx512M MyLuceneApp(或者,但是您啟動Lucene應用程序)
但是,再次,我將使用工具來首先檢查您的內存消耗配置文件和垃圾回收行為。 您的目標應該是避免內存不足,因為這會導致垃圾回收將您的應用程序減慢到無性能的狀態。
第三 。 現在,如果增加堆,則必須確保還具有足夠的本機內存。 因為如果您不這樣做(請使用Linux上的top
工具),您的系統將開始交換到磁盤,這也會瘋狂影響Lucene的性能。 因為Lucene針對順序磁盤讀取進行了優化,並且如果系統開始交換,則硬盤將執行大量磁盤搜索,這比順序讀取慢2個數量級。 因此,情況將會更糟。
第四 。 如果沒有足夠的內存,請考慮分批刪除。 在沖洗1,000或10,000個文檔后,請一次又一次沖洗。 發生OutOfMemoryError的原因是,Lucene必須將所有內容保留在內存中,直到執行刷新為止。 因此,無論如何不要讓太大的批處理沖洗掉,以避免將來出現問題,這可能是一個好主意。
嘗試為您的IndexWriter使用較小的RamBufferedSize。
如果緩沖區已滿(或文檔數達到一定水平),IndexWriter將刷新刷新。 通過將緩沖區大小設置為一個較大的數字,您將隱式推遲調用flush,這可能導致內存中的文檔過多。
在極少數的情況下,我想擦除Lucene索引中的所有文檔,我發現關閉IndexWriter,直接刪除索引文件,然后基本上開始創建新索引的效率更高。 該操作只需要很少的時間,並且可以保證將索引保持原始狀態(如果有些空的話)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.