例如:
先定義一個結構體
Type
Ttest = record
id:dword;
name:string;
ege:word;
memo:string;
end;
var
Atest: array of ttest;
i:integer;
begin
i:=0; isstop:=false;
while isstop<>true do
begin
application.ProcessMessages ;
inc(i);
setlength(atest,i);
atest[i-1].id:=i;
Atest[i-1].name:='張三';
Atest[i-1].ege:=20;
Atest[i-1].memo:='這是一個測驗' ;
edit1.text:=inttostr(i);
end;
end;
//這樣動態定義Atest的長度,我機器跑17000多次就會報錯 Out Of Memory
var
Atest: array of ttest;
i,j:integer;
begin
i:=0; isstop:=false;
j:=100000;
setlength(Atest,j) ;
while i<j do
begin
application.ProcessMessages ;
inc(i);
atest[i-1].id:=i;
Atest[i-1].name:='張三';
Atest[i-1].ege:=20;
Atest[i-1].memo:='這是一個測驗' ;
edit1.text:=inttostr(i);
end;
end;
//這樣一次設定成100000,都不會報錯
請問大家 是如何解決頻繁setlength后報內容溢位錯誤的
沒有分了,都給了
uj5u.com熱心網友回復:
setlength(atest,i);太頻繁,導致記憶體碎片太多!uj5u.com熱心網友回復:
確實不知道總數,可以每次增加50%(不足1000算1000),不夠再增加這樣能大大減少setlength次數
uj5u.com熱心網友回復:
to sz_haitao您說的就是我第二種,我只是想知道,有什么方法可以解決第一種方法里的記憶體溢位錯誤
uj5u.com熱心網友回復:
你這種應該使用TListuj5u.com熱心網友回復:
你這種是記憶體碎片太多,其實總數不算多
你第二種是一次性準確開辟空間
我說的方法是不知道準確空間,但是也使得記憶體碎片不會太多
Tlist也會類似我的做法,所以碎片不會太多
uj5u.com熱心網友回復:
我明白您的意思
uj5u.com熱心網友回復:
看到這突然想到個問題:SetLength重復開辟空間的時候,如果空間里有資料,不會清空的吧?
uj5u.com熱心網友回復:
當然會復制資料過去的,所以必須先開辟新的,再釋放舊的,碎片就這樣形成了
uj5u.com熱心網友回復:
應該考慮申請一塊記憶體反復使用,而不是反復申請。uj5u.com熱心網友回復:
WIN764 XE3我在我機器上運行到2.2千萬多才出錯.提交記憶體達到了1.6G編譯成64位程式,由于64位記憶體可訪問總量太大,我等了幾分鐘也沒出現記憶體不夠用,就結束程式了.
改用TList<T>或者TList存放結構體指標結果更差只有1.6千萬個
以我的機器為例,2.2千萬的時候實際上在setlength的時候最高峰有4.4千萬這個結構體存在.記憶體吃不消也屬正常.
象樓主這種方式記憶體終有窮盡的時候,如果真的需要巨大的資料量一般不會全部用記憶體處理的.舉個例子SQLServer和Oracle等資料程式都必須放在磁盤上,記憶體也就是放一些索引和常用的緩沖.
uj5u.com熱心網友回復:
用TList嘛,多簡單啊。。uj5u.com熱心網友回復:
TList 或 用泛型uj5u.com熱心網友回復:
樓上的搞得都太復雜了,這樣,不要使用record,你宣告一個class從TCollectionItem繼承,將你需要的item宣告成field或property,使用TCollection而不是List來管理這些物件,這樣記憶體使用效率比較高。uj5u.com熱心網友回復:
無限制的開辟資料空間,當然會溢位呀,轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/151917.html
標籤:語言基礎/算法/系統設計
