VARUNA JAYASIRI

@vpj

Parent in (sliced string)

November 23, 2015

img/sliced_string.png

In Google Chrome 1 when you take substrings of a larger string, the larger string is not garbage collected even if it is no longer referenced. The problem seems to be because the substring keeps a reference to the parent string.

Demo

The demo iteratively,

  1. creates a random large string (~10M in length)
  2. take a few substrings (each of about 50 characters)
  3. push the substrings to a global array (the only thing permanently referenced)
  4. remove references to the large string

You would assume that larger strings will get garbage collected. And would expect the program to run without a problem for many many iterations - until the memory taken up by the smaller strings hits the limit.

Unfortunately in Google Chrome it doesn't work like that. The small substrings keep a reference to the parent and therefore it crashes after a few iterations. Try http://vpj.github.io/bench/string_slice.html in Google Chrome.It crashes before 2000 cycles. 2 If you take a heap snapshot on Chrome Inspector, you can see the large strings, referenced as parent in (sliced string) by smaller strings (as shown in the above screenshot).

Then we wrote a copy of the same program, which creates a copy of the substrings before storing them. The following splitting and concatenation creates a actual copy of the string, instead of a reference copy.

newSmallString = smallString.split('').join('')

Try http://vpj.github.io/bench/string_slice_join.html, which will run runs for many more iterations doing the same thing.

1 Same happens in node.js since it uses V8.

2 This only happens in Chrome, not on Safari. Did not check on Firefox.

<!> !img/sliced_string.png In Google Chrome ^^1^^ when you take substrings of a larger string, the larger string is not garbage collected even if it is no longer referenced. The problem seems to be because the substring keeps a reference to the parent string. >>> ^^1^^ Same happens in <<https://nodejs.org/en/(node.js)>> since it uses V8. ## <<<http://vpj.github.io/bench/string_slice.html(Demo)>> The demo iteratively, - creates a random large string (~10M in length) - take a few substrings (each of about 50 characters) - push the substrings to a global array (the only thing permanently referenced) - remove references to the large string You would assume that larger strings will get garbage collected. And would expect the program to run without a problem for many many iterations - until the memory taken up by the smaller strings hits the limit. Unfortunately in Google Chrome it doesn't work like that. The small substrings keep a reference to the parent and therefore it crashes after a few iterations. Try <<http://vpj.github.io/bench/string_slice.html>> in Google Chrome.It crashes before 2000 cycles. ^^2^^ If you take a heap snapshot on Chrome Inspector, you can see the large strings, referenced as **parent in (sliced string)** by smaller strings (as shown in the above screenshot). >>> ^^2^^ This only happens in Chrome, not on Safari. Did not check on Firefox. Then we wrote a copy of the same program, which creates a copy of the substrings before storing them. The following splitting and concatenation creates a actual copy of the string, instead of a reference copy. ```js newSmallString = smallString.split('').join('') Try <<http://vpj.github.io/bench/string_slice_join.html>>, which will run runs for many more iterations doing the same thing.