我使用Delphi 7 XMLDoc單元在XML基礎上構建協議定義,即協議在XML文件中定義,並且一些對象從此XML中獲取信息以分解和構建在TCP/IP上傳送的ISO8583消息。我廣泛使用了IXMLDocument
和IXMLNode
接口。一切都很好,在終止點沒有內存泄漏(使用FASTMM)。但在運行期間,軟件會慢慢消耗內存。釋放對象時以某種方式釋放內存 - 源自TXMLDocument
- 我用於XML訪問。我分析並發現,如果我沒有使用IXMLDocument
和IXMLNode
接口,但是我當然需要的話,沒有內存問題。使用Delphi7的內存問題XMLDoc
我有一個對象(TXMLTree
)從TXMLDocmument
得出:
TXMLTree = class(TXMLDocument, IXMLDocument)
...
end;
我有另一個對象(TDPR
),並在其構造函數創建TXMLTree
並獲得接口(fIDocument
)加上一個接口文檔的起點點(fIDocStart
),以及:
TDPR = class(TObject)
...
fIDocument:IXMLDocument;
fIDocStart:IXMLNode;
...
end;
constructor TDPR.Create(aFilename: string);
begin
inherited;
...
fTree := TXMLTree.Create(aFilename);
fTree.GetInterface(IXMLDocument, fIDocument);
fIDocStart := fIDocument.DocumentElement;
...
end;
一般我使用fIDocument
和fIDocStart
爲起點到達XML文檔,寫這樣的代碼:
node := fIDocument.DocumentElement.ChildNodes[aName].ChildNodes.FindNode(aFieldName);
或
node := fIDocStart.ChildNodes[aName].ChildNodes.FindNode(aFieldName);
只有一個這樣的行,就足以緩慢地提高內存的使用,但如果我在for
循環例如執行它千萬不會有更多的影響,因爲 - 我猜 - 只有一個參考被使用並在循環中一路發佈。
現在,讓我們有一個程序Foo
從哪裏獲得該文件的出發點:
procedure TDPR.Foo;
var lNode:IXMLNode;
begin
lNode := IDocument.DocumentElement;
end;
如果我把這個過程它增加內存使用了一點,但週期性地調用它,它是時間的運行只是時間問題內存不足。
但是:如果我使用fIDocStart
已經存儲所需的接口 - 所以不需要再次調用DocumentElement
- 沒有內存問題。
procedure TDPR.Foo;
var lNode:IXMLNode;
begin
lNode := fIDocStart;
end;
如此看來,每一個獲取並返回一個接口對象(IXMLDocument
IXMLNode
IXMLNodeList
等)調用分配一些內存,並且不釋放它,而參考對象都被正確釋放。即使我們要求同一個節點。當然,我不能存儲所有可能的節點,以避免使用內存。
在TDPR
的析構函數中,我通過將對應接口設置爲nil
來釋放TXMLTree
,並且在終止時未檢測到存儲器泄漏。引用計數器似乎沒問題。
destructor TDPR.Destroy;
begin
...
fIDocStart := nil;
fIDocument := nil;
...
inherited;
end;
而且它無關,與大XML
文件。問題是相同的蒙山XML
這樣的:
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl"?>
<Base24-POS>
<Instructions>
<Parameters Receive="1"/>
</Instructions>
</Base24-POS>
我知道它是模糊的,我只要求拿到有人已經碰到了同樣的問題,可以找到解決方案的機會。 (順便提一句,我記得在WindowsXP中使用的代碼相同,沒有問題,現在是Windows7)
請提供SSCCE –
並檢查您是否沒有存儲接口參考。 – Runner
如果我可能通過不允許釋放對象來存儲會導致內存泄漏的接口引用。但爲什麼它會將內存使用量增加到最終?在程序結束時,沒有檢測到內存泄漏。 – peter