全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:4843
推到 Plurk!
推到 Facebook!

ADO AsVariant 記憶體不會釋放

答題得分者是:mypigbaby
Hans_Han
一般會員


發表:1
回覆:5
積分:1
註冊:2014-06-04

發送簡訊給我
#1 引用回覆 回覆 發表時間:2014-06-04 14:32:19 IP:106.107.xxx.xxx 訂閱
在下遇到一個頭疼的問題. 也很奇怪.

使用D6 開發
資料庫 Oracle 10
資料庫元件 ADO

問題如下
var
chaData: WideString;
begin
...
chaData:=ADO_QUERY.Fieldbyname('DATA').AsVariant;
...
end;
使用 AsVariant時, 記憶體一直飆高. 不會下降. 直到執行檔關閉.
若改用 AsString. 則不會有問題.

我試過把 ADO_QUERY釋放掉, 也沒用.
Hans_Han
一般會員


發表:1
回覆:5
積分:1
註冊:2014-06-04

發送簡訊給我
#2 引用回覆 回覆 發表時間:2014-06-04 14:35:24 IP:106.107.xxx.xxx 訂閱

目前我是先用重整記憶體的方式解決.
但這不是好的辦法.

SetProcessWorkingSetSize(GetCurrentProcess, $FFFFFFFF, $FFFFFFFF);

是否有更好的辦法 ?
leveon
資深會員


發表:30
回覆:389
積分:303
註冊:2012-02-12

發送簡訊給我
#3 引用回覆 回覆 發表時間:2014-06-04 15:00:46 IP:61.228.xxx.xxx 訂閱
程式看起來沒問題
應該 D6的bug

http://qc.embarcadero.com/wc/qcmain.aspx?d=8837


===================引 用 Hans_Han 文 章===================

目前我是先用重整記憶體的方式解決.
但這不是好的辦法.

SetProcessWorkingSetSize(GetCurrentProcess, $FFFFFFFF, $FFFFFFFF);

是否有更好的辦法 ?
mypigbaby
高階會員


發表:11
回覆:168
積分:155
註冊:2006-07-20

發送簡訊給我
#4 引用回覆 回覆 發表時間:2014-06-04 19:06:13 IP:175.181.xxx.xxx 訂閱
剛測試不是WIDESTRING的問題
是.ASVARIANT 不會釋放記憶體
這樣的程式碼也會使記憶體一直衝上去
看來在D7真的不能用VALUE了
[code delphi]
var
v: string;
begin
ADOQuery1.First;
while not adoquery1.Eof do
begin
v:=adoquery1.FieldByName('field1').Value;
ADOQuery1.Next;
end;
[/code]


編輯記錄
mypigbaby 重新編輯於 2014-06-04 19:42:04, 註解 無‧
Hans_Han
一般會員


發表:1
回覆:5
積分:1
註冊:2014-06-04

發送簡訊給我
#5 引用回覆 回覆 發表時間:2014-06-05 13:47:50 IP:210.59.xxx.xxx 訂閱

是阿, 我測試過,變數改用String或是 Variant 接也是一樣.
adoquery 改用動態宣告.再釋放. 還是一樣.

adoquery 下的欄位是屬於TFile元件
我嘗試去針對TFile 處理, 也不行 (程式會出錯)

苦腦找不出解.....
就算是Delphi Bug. 山不轉路轉. 難到沒有其它方式?

===================引 用 mypigbaby 文 章===================
剛測試不是WIDESTRING的問題
是.ASVARIANT 不會釋放記憶體
這樣的程式碼也會使記憶體一直衝上去
看來在D7真的不能用VALUE了
[code delphi]
var
v: string;
begin
ADOQuery1.First;
while not adoquery1.Eof do
begin
v:=adoquery1.FieldByName('field1').Value;
ADOQuery1.Next;
end;
[/code]


aftcast
站務副站長


發表:81
回覆:1485
積分:1763
註冊:2002-11-21

發送簡訊給我
#6 引用回覆 回覆 發表時間:2014-06-06 00:00:48 IP:114.45.xxx.xxx 訂閱
手上沒D6/D7,
至試 BCB6 UPDATE4 (應該對應到D7) 沒問題。
DELPHI XE 版 也沒問題。

所以? D6/D7 才會發生的?
===================引 用 Hans_Han 文 章===================

是阿, 我測試過,變數改用String或是 Variant 接也是一樣.
adoquery 改用動態宣告.再釋放. 還是一樣.

adoquery 下的欄位是屬於TFile元件
我嘗試去針對TFile 處理, 也不行 (程式會出錯)

苦腦找不出解.....
就算是Delphi Bug. 山不轉路轉. 難到沒有其它方式?

===================引 用 mypigbaby 文 章===================
剛測試不是WIDESTRING的問題
是.ASVARIANT 不會釋放記憶體
這樣的程式碼也會使記憶體一直衝上去
看來在D7真的不能用VALUE了
[code delphi]
var
v: string;
begin
ADOQuery1.First;
while not adoquery1.Eof do
begin
v:=adoquery1.FieldByName('field1').Value;
ADOQuery1.Next;
end;
[/code]


------


蕭沖
--All ideas are worthless unless implemented--

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
aftcast
站務副站長


發表:81
回覆:1485
積分:1763
註冊:2002-11-21

發送簡訊給我
#7 引用回覆 回覆 發表時間:2014-06-06 00:57:42 IP:114.45.xxx.xxx 訂閱
若改成下面寫法,會好一點嗎?

var
chaData: WideString;
begin
...
chaData := v;
varClear(v);

...
end;


以上都是憑空以經驗與理論猜想,我沒試過(因沒環境)。參考參考… ^^
------


蕭沖
--All ideas are worthless unless implemented--

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
mypigbaby
高階會員


發表:11
回覆:168
積分:155
註冊:2006-07-20

發送簡訊給我
#8 引用回覆 回覆 發表時間:2014-06-06 08:32:34 IP:60.244.xxx.xxx 訂閱
很奇怪
豬寶寶在公司用D7
就不會發生MEMORY LEAK的問題
版號7.0 (BUILD 8.1)
在家裡用的D7就會發生MEMORY LEAK..
真的好奇怪
Hans_Han兄 你的D7有昇級到UPDATE1嗎?


===================引 用 aftcast 文 章===================
手上沒D6/D7,
至試 BCB6 UPDATE4 (應該對應到D7) 沒問題。
DELPHI XE 版 也沒問題。

所以? D6/D7 才會發生的?
===================引 用 Hans_Han 文 章===================

是阿, 我測試過,變數改用String或是 Variant 接也是一樣.
adoquery 改用動態宣告.再釋放. 還是一樣.

adoquery 下的欄位是屬於TFile元件
我嘗試去針對TFile 處理, 也不行 (程式會出錯)

苦腦找不出解.....
就算是Delphi Bug. 山不轉路轉. 難到沒有其它方式?

===================引 用 mypigbaby 文 章===================
剛測試不是WIDESTRING的問題
是.ASVARIANT 不會釋放記憶體
這樣的程式碼也會使記憶體一直衝上去
看來在D7真的不能用VALUE了
[code delphi]
var
v: string;
begin
ADOQuery1.First;
while not adoquery1.Eof do
begin
v:=adoquery1.FieldByName('field1').Value;
ADOQuery1.Next;
end;
[/code]


Hans_Han
一般會員


發表:1
回覆:5
積分:1
註冊:2014-06-04

發送簡訊給我
#9 引用回覆 回覆 發表時間:2014-06-06 14:02:53 IP:27.245.xxx.xxx 訂閱
真是一語驚省夢中人
我用的是D6 Build 6.163
我來更新版本試試.
(公司只有買D6的版權,我只能用D6)

===================引 用 mypigbaby 文 章===================
很奇怪
豬寶寶在公司用D7
就不會發生MEMORY LEAK的問題
版號7.0 (BUILD 8.1)
在家裡用的D7就會發生MEMORY LEAK..
真的好奇怪
Hans_Han兄 你的D7有昇級到UPDATE1嗎?


Hans_Han
一般會員


發表:1
回覆:5
積分:1
註冊:2014-06-04

發送簡訊給我
#10 引用回覆 回覆 發表時間:2014-06-06 14:08:11 IP:27.245.xxx.xxx 訂閱
這不是變數的問題.
之前有試過您說的方式.沒有成效.
AsVariant會吃Ram. ASStirng 就不會. 由這裡就可以判斷應該不會是變數照成
===================引 用 aftcast 文 章===================
若改成下面寫法,會好一點嗎?

var
chaData: WideString;
begin
...
chaData := v;
varClear(v);

...
end;


以上都是憑空以經驗與理論猜想,我沒試過(因沒環境)。參考參考… ^^
leveon
資深會員


發表:30
回覆:389
積分:303
註冊:2012-02-12

發送簡訊給我
#11 引用回覆 回覆 發表時間:2014-06-06 16:05:54 IP:61.228.xxx.xxx 訂閱


我貼的連結有試過嗎



function GetWideString(field: TWideStringField): Variant;
var
S: WideString;
begin
if field.DataSet.GetFieldData(field, @S, False) then
begin
Result := S;
end else
Result := Null;
end;







===================引 用 Hans_Han 文 章===================
這不是變數的問題.
之前有試過您說的方式.沒有成效.
AsVariant會吃Ram. ASStirng 就不會. 由這裡就可以判斷應該不會是變數照成
===================引 用 aftcast 文 章===================
若改成下面寫法,會好一點嗎?

var
chaData: WideString;
begin
...
chaData := v;
varClear(v);

...
end;


以上都是憑空以經驗與理論猜想,我沒試過(因沒環境)。參考參考… ^^
mypigbaby
高階會員


發表:11
回覆:168
積分:155
註冊:2006-07-20

發送簡訊給我
#12 引用回覆 回覆 發表時間:2014-06-06 19:44:19 IP:175.181.xxx.xxx 訂閱
我真的被這個bug搞胡塗了
同樣的CODE
同樣的D7版本 Build 8.1
家裡的環境是WIN7 X64 SQL 2014
公司的環境是WIN7 X86 SQL 2008
在公司執行不會發生Memory leak
可是在家裡卻會發生Memory leak
哇哩咧
真的不知道該怎麼測這個BUG了= =

aftcast
站務副站長


發表:81
回覆:1485
積分:1763
註冊:2002-11-21

發送簡訊給我
#13 引用回覆 回覆 發表時間:2014-06-06 20:35:07 IP:114.42.xxx.xxx 訂閱
如果我猜的沒錯,應該和wdac/mdac元件的版本有關。以前舊版曾有類似的問題。
假始程式一樣,compiler一樣,會有不同的情形,那就是 driver 或元件的問題。

我試的windows 7 x64 sql2008r2 沒問題。而其mdac/wdac版本是

HKEY_LOCAL_MACHINE\Software\Microsoft\DataAccess

6.1.7601.17514

可以先確定一下是否mdac/wdac (即以上的版本是否一樣)。

接著就測 sqlserver附的driver。 2008 與 2014 不一樣。
不過話說回來,樓主的sql好像是oracle,故… 可很能是 mdac/wdac 造成的機率大一點。



===================引 用 mypigbaby 文 章===================
我真的被這個bug搞胡塗了
同樣的CODE
同樣的D7版本 Build 8.1
家裡的環境是WIN7 X64 SQL 2014
公司的環境是WIN7 X86 SQL 2008
在公司執行不會發生Memory leak
可是在家裡卻會發生Memory leak
哇哩咧
真的不知道該怎麼測這個BUG了= =

------


蕭沖
--All ideas are worthless unless implemented--

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
mypigbaby
高階會員


發表:11
回覆:168
積分:155
註冊:2006-07-20

發送簡訊給我
#14 引用回覆 回覆 發表時間:2014-06-06 21:47:56 IP:175.181.xxx.xxx 訂閱
剛我比對公司跟家裡的版本
都是這個 6.1.7601.17514

===================引 用 aftcast 文 章===================
如果我猜的沒錯,應該和wdac/mdac元件的版本有關。以前舊版曾有類似的問題。
假始程式一樣,compiler一樣,會有不同的情形,那就是 driver 或元件的問題。

我試的windows 7 x64 sql2008r2 沒問題。而其mdac/wdac版本是

HKEY_LOCAL_MACHINE\Software\Microsoft\DataAccess

6.1.7601.17514

可以先確定一下是否mdac/wdac (即以上的版本是否一樣)。

接著就測 sqlserver附的driver。 2008 與 2014 不一樣。
不過話說回來,樓主的sql好像是oracle,故… 可很能是 mdac/wdac 造成的機率大一點。



編輯記錄
mypigbaby 重新編輯於 2014-06-06 21:59:12, 註解 無‧
aftcast
站務副站長


發表:81
回覆:1485
積分:1763
註冊:2002-11-21

發送簡訊給我
#15 引用回覆 回覆 發表時間:2014-06-06 21:56:11 IP:114.42.xxx.xxx 訂閱
嗯。
我也有灌SQL Server Management Studio,且我也沒leak。
有與沒有與sql driver會有關連。

追到這裡…好像也剩這個部份了 :p 。 沒頭緒了! 哈

===================引 用 mypigbaby 文 章===================
剛我比對公司跟家裡的版本
都是這個 6.1.7601.17514
目前豬寶寶是懷疑
公司的機器有灌SQL Server Management Studio
家裡的沒有
會不會是這個的關係?

------


蕭沖
--All ideas are worthless unless implemented--

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
mypigbaby
高階會員


發表:11
回覆:168
積分:155
註冊:2006-07-20

發送簡訊給我
#16 引用回覆 回覆 發表時間:2014-06-06 23:18:08 IP:175.181.xxx.xxx 訂閱
這問題豬寶寶放棄了= =
真的找不出來
我還在win 8.1,WIN7 X86,XP 上面灌D7 Build 8.1
結果統統都會memory leak
唯獨公司的不會
也都灌了SQL Server Management Studio
結果還是leak
目前看起來大多數的OS都會LEAK
就當會LEAK好了= =
反正現在電腦的RAM在比多的
只要不超過2g,應該都還好啦
===================引 用 aftcast 文 章===================
嗯。
我也有灌SQL Server Management Studio,且我也沒leak。
有與沒有與sql driver會有關連。

追到這裡…好像也剩這個部份了 :p 。 沒頭緒了! 哈

===================引 用 mypigbaby 文 章===================
剛我比對公司跟家裡的版本
都是這個 6.1.7601.17514
目前豬寶寶是懷疑
公司的機器有灌SQL Server Management Studio
家裡的沒有
會不會是這個的關係?

aftcast
站務副站長


發表:81
回覆:1485
積分:1763
註冊:2002-11-21

發送簡訊給我
#17 引用回覆 回覆 發表時間:2014-06-06 23:23:11 IP:114.42.xxx.xxx 訂閱
辛苦了! 那我們就先放下吧!  哈哈

待某日,也許我有d7,又剛好遇到leak…我會追進源碼與cpu指令,看到底是啥做怪。不過,此刻沒環境,時間也不是很夠,所以放下囉!

有心人士可以再加油!

雖沒找到答案,但豬寶寶的熱心讓人配服! 給你一個讚!

===================引 用 mypigbaby 文 章===================
這問題豬寶寶放棄了= =
真的找不出來
我還在win 8.1,WIN7 X86,XP 上面灌D7 Build 8.1
結果統統都會memory leak
唯獨公司的不會
也都灌了SQL Server Management Studio
結果還是leak
目前看起來大多數的OS都會LEAK
就當會LEAK好了= =
反正現在電腦的RAM在比多的
只要不超過2g,應該都還好啦
===================引 用 aftcast 文 章===================
嗯。
我也有灌SQL Server Management Studio,且我也沒leak。
有與沒有與sql driver會有關連。

追到這裡…好像也剩這個部份了 :p 。 沒頭緒了! 哈

===================引 用 mypigbaby 文 章===================
剛我比對公司跟家裡的版本
都是這個 6.1.7601.17514
目前豬寶寶是懷疑
公司的機器有灌SQL Server Management Studio
家裡的沒有
會不會是這個的關係?

------


蕭沖
--All ideas are worthless unless implemented--

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
mypigbaby
高階會員


發表:11
回覆:168
積分:155
註冊:2006-07-20

發送簡訊給我
#18 引用回覆 回覆 發表時間:2014-06-06 23:40:25 IP:175.181.xxx.xxx 訂閱
我大概知道原因了
不會LEAK的原因應該在OS
我把家裡會LEAK的SOURCE CODE拿去公司的D7 COMPILE後
拿回家裡跑
會LEAK
但是同一支執行檔
在公司的機器跑卻不會LEAK
豬寶寶還比對過二邊COMPILE出來的執行檔
大小一模一樣,只有幾個BYTE不同
同一支執行檔在不同的電腦跑卻有不同的結果
所以應該是aftcast兄的OS 在MS UPDATE後可能剛好有避掉這個BUG
所以才不會LEAK
結果就是...只要RAM不超過2G..不要管LEAK了啦

===================引 用 aftcast 文 章===================
辛苦了! 那我們就先放下吧! 哈哈

待某日,也許我有d7,又剛好遇到leak…我會追進源碼與cpu指令,看到底是啥做怪。不過,此刻沒環境,時間也不是很夠,所以放下囉!

有心人士可以再加油!

雖沒找到答案,但豬寶寶的熱心讓人配服! 給你一個讚!


Hans_Han
一般會員


發表:1
回覆:5
積分:1
註冊:2014-06-04

發送簡訊給我
#19 引用回覆 回覆 發表時間:2014-06-09 17:35:26 IP:210.59.xxx.xxx 訂閱
謝謝各位的幫助.
感激不盡, 尤其是豬寶寶, 讓您費時費力測試.真是過意不去

我已下載更新包.我在安排時間測試
日後若有結果在告訴大家
謝謝各位
系統時間:2024-04-24 4:17:59
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!