<html> <body> <script> function createString() { return "0".repeat(25 * 1024 * 1024).substring(0, 12); } var arr = []; setInterval(function() { let str = createString(); arr.push(str); }, 500); </script> </body> </html>run it in your browser and open the task manager you could notice that the browser takes some limited amount of memory ~200Mb. But what if we update one single digit in our code
return "0".repeat(25 * 1024 * 1024).substring(0, 13);i.e. replace 12 with 13, run it into a browser and have a look at the process memory. It grows unstoppable and makes the browser crash in a half a minute! Why does it happen?
Every time we call String.prototype.substring function it returns new string instance that keeps .. a link to the original string! That's how V8 organizes memory for strings for permamance reason. Exception is when a new instance string length is less than 13 - in that case no link to original string preserved. So in our example arr contains no just short strings(13), but actually the huge ones (25 * 1024 * 1024). How to avoid it? Unfortunatelly, there is no documemnted method to 'cut' parents from strings, that's because we can do the following (update line 11):
<html> <body> <script> function createString() { return "0".repeat(25 * 1024 * 1024).substring(0, 12); } var arr = []; setInterval(function() { let str = createString().split('').join(''); arr.push(str); }, 500); </script> </body> </html>That manoeuvre breaks the link with the original string and prevents memory leak.
No comments:
Post a Comment