簡體   English   中英

system.outofmemoryexception填充DataAdapter時?

[英]system.outofmemoryexception When filling DataAdapter?

我必須從DB中提取150K記錄。 我使用da.Fill(ds,"Query")和它的投擲system.outofmemoryexception

Dim daGrid As New SqlDataAdapter(sqlcmd_q)
daGrid.Fill(dsGrid, "Query")
daGrid.Dispose()

我只需要這個數據表。 我不能使用XML。 因為我需要將它分配給MSChartControl來顯示ScotterPlot。

有什么建議么?

我要檢查的第一件事是你要返回多少列,以及它們的數據類型。 盡管150K記錄很多,但它不應該給你一個OOM異常,除非每條記錄的長度大約為13K(在32位機器上)。 這告訴我你要么返回的場數多於你需要的字段,要么就是某些字段是非常大的字符串或二進制數據。 嘗試減少select語句,只返回顯示所需的字段。

如果這不起作用,您可能需要從DataTable移動到自定義數據類型列表(具有相應字段的類)。

您沒有指定查詢。 確保它只包含您需要的列。

如果仍有問題,可以嘗試切換到64位(如果您的硬件支持它,並且您有超過2 GB的可用內存)。

如果這沒有幫助你必須減少內存占用。 一種可能的選擇是渲染繪圖而不將所有基礎數​​據存儲在內存中。 只需逐個加載數據,計算坐標並存儲它們,而不存儲基礎記錄。 也許你甚至可以讓查詢這樣做。

我知道這個答案對於幫助原始海報來說已經很晚了,但我希望它可以幫助其他遇到類似問題的人。

首先, DataTable是問題,而不是DataAdapter

問題可能是你真的沒有記憶(在這種情況下,我的答案無濟於事)。 您可以通過數學計算是否可能出現這種情況 - 記錄數x每個記錄的字節數估計。 如果在32位平台上接近2GB或在64位平台上接近可用RAM,則唯一的選擇是減少記錄數,字段數或提出使用DataReader而不是DataTable的方法。

在你的情況下,你有150k記錄,讓我們假設每個記錄需要1KB的內存,這給我們150MB的圓形數字。 即使在具有2GB RAM的32位機器上也應該沒問題(前提是沒有太多類似的內存分配)。 在你的情況下,你有一台64位機器,128GB內存(不錯)。 所以邏輯上你不應該出現內存錯誤。

那導致問題的原因是什么? 它是大對象堆(LOH)。 為什么? DataTable創建一個數組來保存這些記錄。 我的理解是它創建了一個50的數組,然后隨着記錄的增加而增長。 任何超過85,000字節的內存分配都來自大對象堆。 (您使用的是64位平台,因此,一旦您達到10,625條記錄,那么分配將從大對象堆開始。)大對象堆的問題在於它沒有被壓縮。 所以可能有很多可用空間,但沒有足夠大的單個連續塊。 使用.net 4.5 Microsoft已經在合並相鄰片段方面對其進行了改進,但它不會重新組織這些片段以創建更大的可用空間塊。 實際效果是,一旦你根據我的經驗誤入了LOH,你獲得Out of Memory異常只是時間問題。

解決方案?

對我有用的是設置DataTable的初始容量。 從數據庫中提取記錄時,這意味着首先進行計數,因此這會以額外的數據庫查詢為代價,然后:

.
.
dsGrid.InitialCapacity = count;
daGrid.Fill(dsGrid, "Query");
.
.

雖然這不會避免偏離LOH,但它應該意味着它只進行一次分配而不是多次分配。 因此,除了避免內存不足之外,您還應該獲得性能提升(由額外數據庫查詢的需要抵消)。

您可以使.net垃圾收集器壓縮大對象堆,但是您只能告訴它在下次運行時執行此操作。 如果我知道我正在闖入大型對象堆,我傾向於使用它。 這可能有點矯枉過正,但考慮修改我的上述建議:

.
.
dsGrid.InitialCapacity = count;
if (count > 10625)
{
    System.Runtime.GCSettings.LargeObjectHeapCompactionMode =
        System.Runtime.GCLargeObjectHeapCompactionMode.CompactOnce;
}
daGrid.Fill(dsGrid, "Query");
.
.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM