Memory usage increases when you use the eval() function in Internet Explorer 9

Applies to: Internet Explorer 9

Symptoms


Assume that you use the eval() function repeatedly to construct objects from a large JavaScript Object Notation (JSON) string in Windows Internet Explorer 9. In this situation, the memory usage of Internet Explorer 9 increases unexpectedly.

Note This issue does not occur in earlier versions of Internet Explorer.

Cause


This issue occurs because the JavaScript engine in Internet Explorer 9 does not release the code that every call to the eval() function parses until the browsing session ends. Therefore, the memory usage of Internet Explorer 9 increases. The memory is released when you browse or refresh the current webpage.

For an example of the code that causes this issue, see the "Workaround" section.

Note This behavior is by design.

Workaround


To work around this issue in Internet Explorer 9 Standards document compatibility mode or in Internet Explorer 8 Standards document compatibility mode, use the JSON.Parse method to parse JSON strings.

To work around this issue in Internet Explorer 7 Standards document compatibility mode or in Internet Explorer Quirks document compatibility mode, use one of the following methods: 
  • Use the Json2.js JavaScript file to parse JSON strings. You can download the file from the following GitHub website:
  • Use a hidden IFRAME element to evaluate the incoming JSON strings. If you use this method, you must update the IFRAME element periodically.
The following is an example of the code that causes this issue. This example also shows how to evaluate a JSON string by using a hidden IFRAME element or the JSON.parse method.
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=9" />
<title>Repeated Eval Demonstration and Workaround</title>
</head>
<body>
<!-- Create hidden IFrame -->
<iframe id="testframe" style="visibility:hidden; height: 0px; width: 0px"></iframe><br>

<p><button id="bt1" onclick="evalInMain();">Demonstrate Memory Increase with Eval</button>
<button id="bt2" onclick="evalInIFrame();">Demonstrate Eval Workaround with IFrame</button>
<button id="bt3" onclick="JSONparse();">Demonstrate JSON.Parse Workaround</button></p>
<p><button onclick="stopRun();">Stop the run</button></p>
<p>Iterations: <span id="res"> </span></p>
<p>The JSON string is: <br><span id="str"> </span></p>

<script type="text/javascript">
// Assign variables
var dummyTestFrame = document.getElementById("testframe"),
resdiv = document.getElementById("res"),
mainbtn = document.getElementById("bt1"),
iframebtn = document.getElementById("bt2"),
jsonbtn = document.getElementById("bt3"),
iteration = 0,
t,
jsonString = construct_json_string(100),
obj;

document.getElementById("str").innerHTML = jsonString

dummyTestFrame = (dummyTestFrame.contentWindow) ?
dummyTestFrame.contentWindow :
(dummyTestFrame.contentDocument.document) ?
dummyTestFrame.contentDocument.document :
dummyTestFrame.contentDocument;

// Create large JSON String
function construct_json_string(n) {
var json = '{ "JSONstring" : [ ';
for(var i=0; i<=n; ++i) {
json += '{ "a" : ' + i + ' , "b" : ' + i + ' } ';
if(i!=n) { json += ' , ' };
}
json += '] }';
return json;
}

// Create IFrame content. Eval is done in IFrame and object in parent scope is updated
var frame_html = "\n\
<html>\n\
<head><\/head><body>\n\
<script>\n\
function anotherEval(str) {\n\
eval('parent.obj=' + str + ';');\n\
}\n\
<\/script>\n\
<\/body>\n\
<\/html>";

function resetFrame() {
dummyTestFrame.document.open();
dummyTestFrame.document.write(frame_html);
dummyTestFrame.document.close();
}

function disablebuttons() {
mainbtn.disabled=true;
iframebtn.disabled=true;
jsonbtn.disabled=true;
}

// Demonstrates memory increase
var evalInMain = function() {
disablebuttons();
// Example cause
resdiv.innerHTML = iteration++;
eval('obj = ' + jsonString + ';');
t = window.setTimeout(evalInMain, 10);
}

// Demonstrates workaround using eval in IFrame, for IE7 standards document mode
var evalInIFrame = function() {
if (document.documentMode == 7 || document.documentMode == 5)
{ // Workaround
disablebuttons();
resdiv.innerHTML = iteration++;
resetFrame();
dummyTestFrame.anotherEval(jsonString);
t = window.setTimeout(evalInIFrame, 10);
}
else { alert("The hidden iframe workaround is valid for IE7 Standards or Quirks document modes only\n\n You need to change document mode to IE7 Standards or Quirks."); }
}

// Demonstrates workaround using JSON.parse for IE8 standards and IE9 standards document modes
var JSONparse = function() {
if (document.documentMode == 8 || document.documentMode == 9)
{ // Workaround
disablebuttons();
resdiv.innerHTML = iteration++;
obj = JSON.parse(jsonString);
t = window.setTimeout(JSONparse, 10);
}
else { alert("The JSON parse workaround is valid for IE8 and IE9 document modes only\n\n You need to change the doc mode to IE8 or IE9 standards."); }
}

function stopRun() {
resetFrame();
clearTimeout(t);
resdiv.innerHTML = iteration = 0;
mainbtn.disabled=false;
iframebtn.disabled=false;
jsonbtn.disabled=false;
}
</script>
</body>
</html>

More Information


For more information about JSON strings, visit the following JSON website: Microsoft provides third-party contact information to help you find technical support. This contact information may change without notice. Microsoft does not guarantee the accuracy of this third-party contact information.