A
Archimedes Trajano
I wrote out a simple experiment to test changing the contents of an
IFrame using src and I found that it leaks when I change the src
attribute. This happens in Internet Explorer 6 but I have not tried
to do measurements on other browsers. The leak only manifests when
using PerfMon to monitor the private bytes over time for the
iexplore.exe process. I have verified that sIEve will not show any
leaks.
I actually found a solution that does not use the src attribute that
does not leak, but I am trying to determine if I am alone in seeing
this behaviour/leak pattern (which I don't I am alone). The leak
shows a linear growth and it becomes visible as the the "click me"
text is clicked continuously.
The closest topics that I found when researching this problem are in
the comp.lang.javascript newsgroup. However, both do not state any
working result.
* Dan Edgar - Internet Explorer Massive IFRAME Memory Leaks
* Tõnu Näks - Javascript Memory Leak
At present I am still trying to retrofit my non-leaking solution into
an existing framework with no luck, so I am trying to see if there are
other known workarounds on this behaviour so I don't need to make many
invasive changes in the framework. The solution that does not leak
uses Ajax in using the prototypejs library and do a document.write(),
document.close() to clear and replace the content.
The following is the leaking source. I have tried to keep it as short
as possible and add as much comments as possible.
<html>
<head>
<style>
..bufferFrame {
display: block; /* for now so we can see the contents of the buffer
frame */
position: absolute; top: 0; left: 1024px; width: 1024px; height:
768px;
}
..appFrame {
display: block;
position: absolute; top: 0; left: 1024px; width: 1024px; height:
768px;
}
</style>
<script>
var onFrame = 0;
// This gets executed when the page gets loaded
// Used this approach to get rid of the closure and obvious leak shown
in sIEve
function handleSwitch() {
document.all[onFrame].className = "bufferFrame"
event.srcElement.className = "appFrame"
onFrame = event.srcElement.id
}
// page = URL
// obj = the object that triggered the event
function nav(page,obj) {
// Prevent double clicks
obj.onmousedown = null
var bufferFrame = (onFrame == "frame0") ? "frame1": "frame0"
document.all[bufferFrame].src = page
document.all[bufferFrame].attachEvent("onload", handleSwitch)
}
function load() {
onFrame = "frame0";
}
</script>
</head>
<body onload="load()">
<iframe id="frame0" src="buffer1.html" class="appFrame"></iframe>
<iframe id="frame1" src="foo.html" class="bufferFrame"></iframe>
</body>
</html>
The contents of buffer1.html starts with
<html>
<head>
<title>buffer1</title>
</head>
<body id="bbuffer1" >
<p>Buffer 1</p>
<div id="buffer1" onmousedown='top.nav("buffer2.html", this)'>click
me</div>
<p>
.... large number of text about 100K to make the memory grow as
quickly as possible, I use the http://www.lipsum.com/ to generate the
text
</p>
</body>
</html>
There is a buffer2.html file which is the same as buffer1.html except
it points to buffer3.html
<html>
<head>
<title>buffer2</title>
</head>
<body id="bbuffer2" >
<p>Buffer 2</p>
<div id="buffer1" onmousedown='top.nav("buffer3.html", this)'>click
me</div>
<p>
.... large number of text about 2MB to make the memory grow as quickly
as possible, I use the http://www.lipsum.com/ to generate the text
</p>
</body>
</html>
There is a buffer3.html file which is the same as buffer1.html except
it points to buffer1.html
<html>
<head>
<title>buffer3</title>
</head>
<body id="bbuffer3" >
<p>Buffer 3</p>
<div id="buffer1" onmousedown='top.nav("buffer1.html", this)'>click
me</div>
<p>
.... large number of text about 1MB to make the memory grow as quickly
as possible, I use the http://www.lipsum.com/ to generate the text
</p>
</body>
</html>
foo.html is just
<p>foo</p>
IFrame using src and I found that it leaks when I change the src
attribute. This happens in Internet Explorer 6 but I have not tried
to do measurements on other browsers. The leak only manifests when
using PerfMon to monitor the private bytes over time for the
iexplore.exe process. I have verified that sIEve will not show any
leaks.
I actually found a solution that does not use the src attribute that
does not leak, but I am trying to determine if I am alone in seeing
this behaviour/leak pattern (which I don't I am alone). The leak
shows a linear growth and it becomes visible as the the "click me"
text is clicked continuously.
The closest topics that I found when researching this problem are in
the comp.lang.javascript newsgroup. However, both do not state any
working result.
* Dan Edgar - Internet Explorer Massive IFRAME Memory Leaks
* Tõnu Näks - Javascript Memory Leak
At present I am still trying to retrofit my non-leaking solution into
an existing framework with no luck, so I am trying to see if there are
other known workarounds on this behaviour so I don't need to make many
invasive changes in the framework. The solution that does not leak
uses Ajax in using the prototypejs library and do a document.write(),
document.close() to clear and replace the content.
The following is the leaking source. I have tried to keep it as short
as possible and add as much comments as possible.
<html>
<head>
<style>
..bufferFrame {
display: block; /* for now so we can see the contents of the buffer
frame */
position: absolute; top: 0; left: 1024px; width: 1024px; height:
768px;
}
..appFrame {
display: block;
position: absolute; top: 0; left: 1024px; width: 1024px; height:
768px;
}
</style>
<script>
var onFrame = 0;
// This gets executed when the page gets loaded
// Used this approach to get rid of the closure and obvious leak shown
in sIEve
function handleSwitch() {
document.all[onFrame].className = "bufferFrame"
event.srcElement.className = "appFrame"
onFrame = event.srcElement.id
}
// page = URL
// obj = the object that triggered the event
function nav(page,obj) {
// Prevent double clicks
obj.onmousedown = null
var bufferFrame = (onFrame == "frame0") ? "frame1": "frame0"
document.all[bufferFrame].src = page
document.all[bufferFrame].attachEvent("onload", handleSwitch)
}
function load() {
onFrame = "frame0";
}
</script>
</head>
<body onload="load()">
<iframe id="frame0" src="buffer1.html" class="appFrame"></iframe>
<iframe id="frame1" src="foo.html" class="bufferFrame"></iframe>
</body>
</html>
The contents of buffer1.html starts with
<html>
<head>
<title>buffer1</title>
</head>
<body id="bbuffer1" >
<p>Buffer 1</p>
<div id="buffer1" onmousedown='top.nav("buffer2.html", this)'>click
me</div>
<p>
.... large number of text about 100K to make the memory grow as
quickly as possible, I use the http://www.lipsum.com/ to generate the
text
</p>
</body>
</html>
There is a buffer2.html file which is the same as buffer1.html except
it points to buffer3.html
<html>
<head>
<title>buffer2</title>
</head>
<body id="bbuffer2" >
<p>Buffer 2</p>
<div id="buffer1" onmousedown='top.nav("buffer3.html", this)'>click
me</div>
<p>
.... large number of text about 2MB to make the memory grow as quickly
as possible, I use the http://www.lipsum.com/ to generate the text
</p>
</body>
</html>
There is a buffer3.html file which is the same as buffer1.html except
it points to buffer1.html
<html>
<head>
<title>buffer3</title>
</head>
<body id="bbuffer3" >
<p>Buffer 3</p>
<div id="buffer1" onmousedown='top.nav("buffer1.html", this)'>click
me</div>
<p>
.... large number of text about 1MB to make the memory grow as quickly
as possible, I use the http://www.lipsum.com/ to generate the text
</p>
</body>
</html>
foo.html is just
<p>foo</p>