Issue 2869 in v8: Substring of huge string retains huge string in memory

249 views
Skip to first unread message

ricardo.… via monorail

unread,
Sep 12, 2016, 9:17:06 PM9/12/16
to v8-re...@googlegroups.com

Comment #8 on issue 2869 by ricardo....@gmail.com: Substring of huge string retains huge string in memory
https://bugs.chromium.org/p/v8/issues/detail?id=2869#c8

Guys, people are starting to propose hacks as workaround for this bug :(

https://github.com/mrdoob/three.js/issues/9679
https://github.com/mrdoob/three.js/pull/9680/files

--
You received this message because:
1. The project was configured to send all issue notifications to this address

You may adjust your notification preferences at:
https://bugs.chromium.org/hosting/settings

k… via monorail

unread,
Sep 13, 2016, 1:03:16 PM9/13/16
to v8-re...@googlegroups.com
Updates:
Cc: -sven...@chromium.org k...@chromium.org hpa...@chromium.org
Labels: -Priority-Low -Type-FeatureRequest OS-All Priority-Medium Type-Bug

Comment #9 on issue 2869 by k...@chromium.org: Substring of huge string retains huge string in memory
https://bugs.chromium.org/p/v8/issues/detail?id=2869#c9

This is affecting the most popular JavaScript library for drawing 3D graphics on the web. Per the above links, could this please be given some more thought? Thanks.

k… via monorail

unread,
Sep 13, 2016, 1:04:04 PM9/13/16
to v8-re...@googlegroups.com
Updates:
Components: Runtime Language

Comment #10 on issue 2869 by k...@chromium.org: Substring of huge string retains huge string in memory
https://bugs.chromium.org/p/v8/issues/detail?id=2869#c10

(No comment was entered for this change.)

ad… via monorail

unread,
Sep 13, 2016, 1:20:54 PM9/13/16
to v8-re...@googlegroups.com
Updates:
Components: -Language

Comment #11 on issue 2869 by ad...@chromium.org: Substring of huge string retains huge string in memory
https://bugs.chromium.org/p/v8/issues/detail?id=2869#c11

jkumme… via monorail

unread,
Mar 28, 2018, 10:06:20 PM3/28/18
to v8-re...@googlegroups.com
Updates:
Cc: yukis...@chromium.org jkum...@chromium.org ad...@chromium.org ish...@chromium.org vamshi....@chromium.org

Comment #14 on issue 2869 by jkum...@chromium.org: Substring of huge string retains huge string in memory
https://bugs.chromium.org/p/v8/issues/detail?id=2869#c14

Issue chromium:822249 has been merged into this issue.

bro… via monorail

unread,
Apr 2, 2018, 2:32:23 PM4/2/18
to v8-re...@googlegroups.com

Comment #15 on issue 2869 by bro...@gmail.com: Substring of huge string retains huge string in memory
https://bugs.chromium.org/p/v8/issues/detail?id=2869#c15

Add https://github.com/kelektiv/node-uuid/pull/267 to the list projects being asked to hack around this.

zac.spit… via monorail

unread,
Apr 12, 2018, 6:19:22 AM4/12/18
to v8-re...@googlegroups.com

Comment #16 on issue 2869 by zac.spit...@gmail.com: Substring of huge string retains huge string in memory
https://bugs.chromium.org/p/v8/issues/detail?id=2869#c16

another post about a workaround for this https://www.just-bi.nl/a-tale-of-a-javascript-memory-leak/

david.vu… via monorail

unread,
Dec 17, 2018, 4:34:23 AM12/17/18
to v8-re...@googlegroups.com

Comment #17 on issue 2869 by david.vu...@gmail.com: Substring of huge string retains huge string in memory
https://bugs.chromium.org/p/v8/issues/detail?id=2869#c17

Can someone please shed some light on whether there is a plan for how to deal with this issue?

This is not an academic matter, it is unexpected behaviour that leads to real bugs and requires creative workarounds. These serve only as temporary measures as it would be really easy to accidentally trigger such leaks again by adding a single line of code somewhere.

On my end, our use case is Node.js - latest LTS - and I could live with --no-string-slices and take whatever performance hit that might imply - however from what I can tell this option is either ignored or not working, depending on what version of V8 is used. It looks like this is a V8 issue, not a Node.js issue per se.

I'm not sure to what extent that approach would solve things for other people, but it would be a start.

Thank you.

yang… via monorail

unread,
Dec 17, 2018, 4:54:51 AM12/17/18
to v8-re...@googlegroups.com

Comment #18 on issue 2869 by yan...@chromium.org: Substring of huge string retains huge string in memory
https://bugs.chromium.org/p/v8/issues/detail?id=2869#c18

--no-string-slices is a flag you need to set at build time. At runtime it becomes read-only.

david.vu… via monorail

unread,
Dec 17, 2018, 5:20:01 AM12/17/18
to v8-re...@googlegroups.com

Comment #19 on issue 2869 by david.vu...@gmail.com: Substring of huge string retains huge string in memory
https://bugs.chromium.org/p/v8/issues/detail?id=2869#c19

Would it be possible in some way to provide a runtime flag for toggling string slices? I'd like to know the situation as best I can before I talk to the Node.js folks.

david.vu… via monorail

unread,
Jan 31, 2019, 6:02:18 AM1/31/19
to v8-re...@googlegroups.com

Comment #20 on issue 2869 by david.vu...@gmail.com: Substring of huge string retains huge string in memory
https://bugs.chromium.org/p/v8/issues/detail?id=2869#c20

Created a Node issue: https://github.com/nodejs/node/issues/25846

david.vu… via monorail

unread,
Mar 28, 2019, 8:39:09 AM3/28/19
to v8-re...@googlegroups.com

Comment #21 on issue 2869 by david.vu...@gmail.com: Substring of huge string retains huge string in memory
https://bugs.chromium.org/p/v8/issues/detail?id=2869#c21

Quoting from said Node issue:

"AFAIK there is little that can be done in a generic fashion. Since the flag is a build flag we can also not provide a runtime flag.

This is definitely something the @nodejs/v8 team has to find a solution for.

For these reasons I am closing the issue. If anyone has more insight, please leave a comment / reopen."

Can you please comment on this?

yang… via monorail

unread,
Nov 22, 2019, 5:45:28 AM11/22/19
to v8-re...@googlegroups.com
Updates:
Owner: ----
Status: Available

Comment #22 on issue 2869 by yan...@chromium.org: Substring of huge string retains huge string in memory
https://bugs.chromium.org/p/v8/issues/detail?id=2869#c22


(No comment was entered for this change.)

a… via monorail

unread,
Jan 1, 2020, 11:54:33 AM1/1/20
to v8-re...@googlegroups.com

Comment #23 on issue 2869 by a...@adamhooper.com: Substring of huge string retains huge string in memory
https://bugs.chromium.org/p/v8/issues/detail?id=2869#c23

I keep hearing of people running into this issue, so I'll brainstorm some ideas:

1. Modify the language specification so this bug becomes a feature

In Go, the leak is built in to the language specification: Slices explicitly reference their underlying Arrays. Go developers can easily understand the problem, and the solution is intuitive. The problem and solution are documented in a couple of paragraphs at https://blog.golang.org/go-slices-usage-and-internals.

Here's that idea applied to JavaScript. The JavaScript spec would document that a String consists of a "backing store" and "slice". Each String method specifies whether it reuses an argument's "backing store." And finally, there would be a force-copy function so users had a clear workaround -- for instance, "`new String()` always creates a new backing store."

2. Stop slicing

In OpenJDK, Java Strings used to share a backing store. In 2012, they simply ... stopped. If I'm reading correctly, the OpenJDK community determined that the harm of shared backing stores outweighed the good. http://mail.openjdk.java.net/pipermail/core-libs-dev/2012-May/010257.html

Should V8 do the same? Are shared backing stores doing more harm than good, as they did in OpenJDK? (Perhaps shared backing stores are better on 32-bit architectures than on 64-bit architectures, and the whole idea is now an expensive relic?)

3. Use two kinds of string.

Rust is explicit about `str` being a slice ("borrowing" from a backing store) and `String` being not-a-slice: https://doc.rust-lang.org/std/primitive.str.html https://doc.rust-lang.org/std/string/struct.String.html This makes it easy to reason about what objects consume memory.

C++17 has a similar dichotomy: `std::string` is akin to a Rust `String` ("backing store + length"), and the new `std::string_view` is akin to a Rust `str` ("[borrowed] pointer + length").

(Yes, Go Slices are kinda the same thing. But Rust and C++ aren't garbage-collected, so Rust/C++ developers think in terms of "ownership" and "borrowing".)

JavaScript could do something similar, and there's already an opening: JavaScript already _has_ two kinds of string! Maybe "primitive string" could be a "slice" and "String" could be a "not-a-slice", or maybe vice-versa. (This probably can't be achieved without big changes to the language spec ... but cut me some slack -- I'm brainstorming here :).)

...

Personally, I'm really curious about my second idea. OpenJDK made the switch; why shouldn't V8?

verwa… via monorail

unread,
Jan 7, 2020, 8:21:00 AM1/7/20
to v8-re...@googlegroups.com
Updates:
Cc: les...@chromium.org

Comment #24 on issue 2869 by verwa...@chromium.org: Substring of huge string retains huge string in memory
https://bugs.chromium.org/p/v8/issues/detail?id=2869#c24


(No comment was entered for this change.)

lesz… via monorail

unread,
Feb 24, 2020, 4:24:20 AM2/24/20
to v8-re...@googlegroups.com
Updates:
Cc: verwa...@chromium.org dinf...@google.com

Comment #26 on issue 2869 by les...@chromium.org: Substring of huge string retains huge string in memory
https://bugs.chromium.org/p/v8/issues/detail?id=2869#c26

Issue 10253 has been merged into this issue.

lesz… via monorail

unread,
Feb 24, 2020, 4:39:58 AM2/24/20
to v8-re...@googlegroups.com

Comment #27 on issue 2869 by les...@chromium.org: Substring of huge string retains huge string in memory
https://bugs.chromium.org/p/v8/issues/detail?id=2869#c27

I've got an old, mostly abandoned patch to clean-up slices if all the slices of a string added together take up less space than the original string (https://crrev.com/c/1087000). It's currently in a mostly-abandoned state, the problem is that this has an impact on the stop-the-world main-thread pause, which slows down your program if you use sliced strings at all. Worse, if your sliced strings are actually a good idea, it slows down your program _more_, because they don't get removed and are re-counted on every GC! It's a space I want to explore again but it's a hard problem, and unfortunately somewhat of an edge case when compared to GC in general.

verwa… via monorail

unread,
Feb 25, 2020, 8:53:42 AM2/25/20
to v8-re...@googlegroups.com
Updates:
Cc: -ad...@chromium.org
Labels: Priority-3 Type-FeatureRequest
Owner: les...@chromium.org
Status: Assigned

Comment #28 on issue 2869 by verwa...@chromium.org: Substring of huge string retains huge string in memory
https://bugs.chromium.org/p/v8/issues/detail?id=2869#c28


(No comment was entered for this change.)

plins… via monorail

unread,
Dec 29, 2020, 10:29:36 AM12/29/20
to v8-re...@googlegroups.com

Comment #29 on issue 2869 by plins...@gmail.com: Substring of huge string retains huge string in memory
https://bugs.chromium.org/p/v8/issues/detail?id=2869#c29

[This StackOverflow answer](https://stackoverflow.com/a/57468694/157955) suggests using `String.prototype.repeat()`. Unfortunately, this doesn't appear to actually do the trick with current versions of Chrome. However, perhaps that would be a better workaround than the slice / concatenate / slice approach that does work.

The [MDN docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat) say that `repeat` "constructs and returns a new string". Could be good to treat usage of this (or, at least, of `repeat(1)`) as an indication of developer intent.

tiger… via monorail

unread,
Jan 26, 2023, 5:23:38 PM1/26/23
to v8-re...@googlegroups.com

Comment #30 on issue 2869 by tiger...@gmail.com: Substring of huge string retains huge string in memory
https://bugs.chromium.org/p/v8/issues/detail?id=2869#c30

10 years later this bug is still present - and even more aggressive than before. None of the hacks work anymore.
I use a webworker that parses huge XML strings with RegEx in TV apps with limited RAM. That bug kills TVs! Please fix.

rh… via monorail

unread,
Jan 27, 2023, 8:45:31 AM1/27/23
to v8-re...@googlegroups.com

Comment #31 on issue 2869 by rh...@raymondhill.net: Substring of huge string retains huge string in memory
https://bugs.chromium.org/p/v8/issues/detail?id=2869#c31


> None of the hacks work anymore

Have you tried something like the following?

let s = JSON.parse(JSON.stringify(bigstr.slice(...));

lesz… via monorail

unread,
Feb 6, 2023, 6:12:14 AM2/6/23
to v8-re...@googlegroups.com
Updates:
Cc: mlip...@chromium.org

Comment #32 on issue 2869 by les...@chromium.org: Substring of huge string retains huge string in memory
https://bugs.chromium.org/p/v8/issues/detail?id=2869#c32

The `JSON.parse(JSON.stringify(...))` trick should work, as would anything that involves "internalizing" the string, such as using it as a key in a keyed lookup.

Unfortunately, I don't have any updates on this since comment #27, and the tradeoff space hasn't changed since then (we haven't figured out a way to improve this edge case without slowing down the general case). It falls into a certain class of problems where the cure is worse than the disease, see also the issues we have around context value keep-alive. It's possible that if this is killing TVs, it's something we could do only in rare cases for critical memory pressure? +mlippautz

mlipp… via monorail

unread,
Feb 6, 2023, 6:29:59 AM2/6/23
to v8-re...@googlegroups.com

Comment #33 on issue 2869 by mlip...@chromium.org: Substring of huge string retains huge string in memory
https://bugs.chromium.org/p/v8/issues/detail?id=2869#c33

It's possible to make the concurrent marker keep track of substrings and use this information later for postprocessing to decide when copying out would be better based on some heuristic.

We currently have no resources to work on this but would accept patches integrating this in an optional way.

tiger… via monorail

unread,
Feb 6, 2023, 5:33:26 PM2/6/23
to v8-re...@googlegroups.com

Comment #34 on issue 2869 by tiger...@gmail.com: Substring of huge string retains huge string in memory
https://bugs.chromium.org/p/v8/issues/detail?id=2869#c34

Also tried with JSON:

var aMatches = JSON.parse(JSON.stringify(sXml.match(/<channel[^>]*>([\s\S]*?)<\/channel>/g)));

Still memory leak, that cannot be freed by GC. I created a demo-page for this: http://m3u-ip.tv/memory-leak.html

a… via monorail

unread,
Feb 6, 2023, 7:16:15 PM2/6/23
to v8-re...@googlegroups.com

Comment #35 on issue 2869 by a...@adamhooper.com: Substring of huge string retains huge string in memory
https://bugs.chromium.org/p/v8/issues/detail?id=2869#c35

Has anybody tried the workaround in the original bug report? It's the first instance of the word "workaround" on this very page.

dinfu… via monorail

unread,
Feb 7, 2023, 2:38:10 AM2/7/23
to v8-re...@googlegroups.com

Comment #36 on issue 2869 by dinf...@chromium.org: Substring of huge string retains huge string in memory
https://bugs.chromium.org/p/v8/issues/detail?id=2869#c36

@tigerleon: I think this is a leak caused by https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/lastMatch. This has nothing to do with this substring issue.

dinfu… via monorail

unread,
Feb 7, 2023, 3:21:17 AM2/7/23
to v8-re...@googlegroups.com

Comment #37 on issue 2869 by dinf...@chromium.org: Substring of huge string retains huge string in memory
https://bugs.chromium.org/p/v8/issues/detail?id=2869#c37

Btw: You should be able to fix that leak by running `/./.exec("a")` afterwards (at least it worked for me locally). That resets that lastMatch property. It's definitely unfortunate but necessary for JS compatibility.

lesz… via monorail

unread,
Feb 7, 2023, 5:17:55 AM2/7/23
to v8-re...@googlegroups.com

Comment #38 on issue 2869 by les...@chromium.org: Substring of huge string retains huge string in memory
https://bugs.chromium.org/p/v8/issues/detail?id=2869#c38

I'd rather expect Regexp.input / Regexp.$_ to be the issue here (rather than lastMatch), but those only make it worse since they specifically require keeping the input string. The leak fix dinuehr@ posted would fix this too.

tiger… via monorail

unread,
Feb 7, 2023, 9:59:15 AM2/7/23
to v8-re...@googlegroups.com

Comment #39 on issue 2869 by tiger...@gmail.com: Substring of huge string retains huge string in memory
https://bugs.chromium.org/p/v8/issues/detail?id=2869#c39

@dinfuehr: thank you very much for the fix with /./.exec("a"). This solves indeed the memory-leak of lastMatch/lastIndex. But not in Worker-script :) Any idea on that?

dinfu… via monorail

unread,
Feb 7, 2023, 10:56:47 AM2/7/23
to v8-re...@googlegroups.com

Comment #40 on issue 2869 by dinf...@chromium.org: Substring of huge string retains huge string in memory
https://bugs.chromium.org/p/v8/issues/detail?id=2869#c40

@tigerleon: You can try to use the Memory tab in DevTools to investigate this yourself. If you have a repro for that case as well I guess I could take a quick look.
Reply all
Reply to author
Forward
0 new messages