Memory leak i javascript (xmlhttprequest) med Safari
HejJeg har de sidste par dage været ved at teste memory leak i javascript når man bruger Safari og XmlHttpRequest.
For at simulere en side der vises i et par uger har jeg lavet et script der består i at hente en xml-fil en masse gange. Jeg har så holdt øje med hukommelsesforbruget og kan se at det stiger løbende og ikke bliver garbage collected. Og for hver 10.000'ende måling kan jeg se at der går længere og længere tid.
Kører jeg det samme script i Firefox er der ingen problemer. Hvor går det galt?
Filerne jeg bruger:
index.html:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>Javascript test</title>
<script type="text/javascript" src="xml.js"></script>
</head>
<body>
<p>
<input type="button" onclick="startScript();" value="Start"/>
</p>
<p id="count">Counter: Not started!</p>
</body>
</html>
xml.js:
var xmlDoc;
var counter = 0;
function startScript()
{
document.getElementById('count').innerHTML = 'Counter: ' + counter++;
xmlDoc = getDomAdapter("status.xml", verify).createDocument();
}
function verify()
{
if (xmlDoc.readyState == 4)
{
delete httpreq['onreadystatechange']; //Sletter eventlistener
delete xmlDoc['onreadystatechange']; //Sletter eventlistener
xmlDoc = null;
setTimeout("startScript()", 1);
}
}
var httpreq;
//
// Returnerer en adapter til DOM.
//
function getDomAdapter(_filename, callback)
{
if('undefined' != typeof XMLHttpRequest)
{
adapter = 'SA'; //Safari
//console.log("Safari browser");
}
switch (adapter) {
case 'SA':
return new (function() {
this.createDocument = function() {
//console.log("httpreq: " + httpreq);
if(httpreq != null)
{
httpreq.onreadystatechange = null;
httpreq.abort();
}
else
{
httpreq = new XMLHttpRequest();
}
try {
httpreq.open("GET", _filename, true);
httpreq.onreadystatechange = callback;
httpreq.send(null);
}
catch (e) {
console.log(e);
}
return httpreq;
};
this.serialize = function(doc) {
return new XMLSerializer().serializeToString(doc);
};
this.parseXml = function(xml) {
var doc = new DOMParser().parseFromString(xml, "text/xml");
if ("parsererror" == doc.documentElement.nodeName) {
throw new Error('Parse error');
}
return doc;
};
})();
default:
throw new Error('Unable to select the DOM adapter');
}
};
status.xml
<Root></Root>