我們有一個定期讀取CSV文件並將記錄插入Oracle 11g數據庫的ColdFusion 9腳本。 CSV文件大約有50列,其中8個由CF使用(CSV格式不能修改)。該CFM的一般流程是:讀取用於數據庫導入的csv文件時ColdFusion內存尖峯化
- 讀取使用該變量作爲與CHR作爲分隔符的列表屬性(13)文件導入可變
- CFLOOP
- 呼叫Oracle存儲過程中插入來自各個值使用ListGetAt
存儲過程文件執行下列操作:
- 插入具有2網絡連接的記錄視場爲表1
- 插入8個領域(包括表1的主鍵)爲表2
- 沒有返回值
這成功地運行在大多數情況下,閱讀數以百計的記錄400頁KB的文件記錄只需幾秒鐘。但是,偶爾我們會得到一個大容量,並且最終創建一個13k創紀錄的5MB文件。當我們嘗試處理一個這樣大的文件時,我觀察到JVM的內存使用量在10-15秒內從90MB增加到680MB左右,之後CF服務器監視器停止響應(CF也如此),迫使我們重新啓動服務。日誌報告JVM內存不足錯誤:
"Error","qtp4795249-38798","12/28/11","16:29:20",,"GC overhead limit exceeded" java.lang.OutOfMemoryError: GC overhead limit exceeded
我們的JVM堆大小目前是768MB。我還沒有嘗試過增加它,因爲即使這樣做確實解決了這個問題,它將來也無法保護我們,而服務器的其他正常負載並不需要那麼多。而且,我對使用JVM設置需要重啓才能在生產環境中生效的做法感到猶豫不決。
這很難測試,因爲導入過程運行正常,幾乎沒有任何明顯的內存負載在我的本地開發機器和我們的QA盒子上,但是這兩者與數據庫的連接速度要慢得多,需要10-15分鐘去完成。
我會很感激任何想法,特別是關於內存的去向。我無法弄清楚5MB數據如何變成700MB的數據。我們打開了調試信息,但調用腳本的IP地址不在調試列表中,我使用了一個cfsetting標籤來關閉此頁面的調試功能。以前,有一個步驟1.5將CSV數據轉換爲ColdFusion查詢,但我爲了提高效率而將其刪除。兩種方式都會導致錯誤。
感謝所有的迴應。由於客戶發生的月末和年終處理,以及他們昨天對CF服務器持續30秒的響應,我們將等待一週左右,然後嘗試實施或測試任何這些建議。然後我會更新這個問題。 – Nicholas 2011-12-30 18:49:05