Skip to content

Generator functions - memory leak #30753

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
assaf-xm opened this issue Dec 1, 2019 · 6 comments
Closed

Generator functions - memory leak #30753

assaf-xm opened this issue Dec 1, 2019 · 6 comments
Labels
v8 engine Issues and PRs related to the V8 dependency.

Comments

@assaf-xm
Copy link

assaf-xm commented Dec 1, 2019

Environment:

  • Version: v12.13.1
  • Platform: Linux server 4.4.0-36-generic (Ubuntu - 20GB RAM)

Probably a V8 issue, but can severely affect the stability of node.js processes.
This issue doesn't reproduce with node 10.13, only with node 12.

With the below simple code, I manage to get an internal array with more than 112M cells which cause the 'invalid array length' fatal error.

This isn't a real 'out of memory' issue, but an array size limit error.
It reproduces also when increasing the old space size using '--max-old-space-size=8192' (process halts ~1.2GB in any case).

"use strict";
const co = require('co');

function* test() {
    for (let i = 0; i < 1000000000; i++) {
        function* a() {}
        yield* a(); 
        if (i % 1000000 == 0) {
            console.log("Cycle", i, process.memoryUsage().heapUsed);
        }
    }
}

co(function*(){
    yield* test();
})

After few minutes at cycle 105M, the node process crash with the following error:

Cycle 105000000 1176098488

<--- Last few GCs --->

[6422:0x3a3feb0]   262277 ms: Scavenge 1161.3 (1178.4) -> 1150.5 (1181.7) MB, 6.2 / 0.0 ms  (average mu = 0.939, current mu = 0.939) allocation failure 
[6422:0x3a3feb0]   262336 ms: Scavenge 1174.1 (1191.4) -> 1163.3 (1194.7) MB, 6.5 / 0.0 ms  (average mu = 0.939, current mu = 0.939) allocation failure 
[6422:0x3a3feb0]   262395 ms: Scavenge 1186.8 (1203.9) -> 1176.0 (1207.2) MB, 7.0 / 0.0 ms  (average mu = 0.939, current mu = 0.939) allocation failure 


<--- JS stacktrace --->

==== JS stack trace =========================================

    0: ExitFrame [pc: 0x1374fd9]
Security context: 0x2d89a7ac08a1 <JSObject>
    1: test(aka test) [0x3038f06001e9] [/home/test_generators/test_generators.js:~4] [pc=0x3dbc7f842f1e](this=0x38a3372404a9 <undefined>)
    2: next [0x2d89a7ae3651](this=0x3038f0600149 <JSGenerator>,0x38a3372404a9 <undefined>)
    3: /* anonymous */ [0x3038f06002c9] [/home/test_generators/test_generators.js:15] [bytecode=0x10099225ec79 offset=88](th...

FATAL ERROR: invalid array length Allocation failed - JavaScript heap out of memory
 1: 0x9da7c0 node::Abort() [node]
 2: 0x9db976 node::OnFatalError(char const*, char const*) [node]
 3: 0xb39f1e v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [node]
 4: 0xb3a299 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [node]
 5: 0xce5635  [node]
 6: 0xcc24a5 v8::internal::Factory::CopyWeakArrayListAndGrow(v8::internal::Handle<v8::internal::WeakArrayList>, int, v8::internal::AllocationType) [node]
 7: 0xebe86a v8::internal::WeakArrayList::EnsureSpace(v8::internal::Isolate*, v8::internal::Handle<v8::internal::WeakArrayList>, int, v8::internal::AllocationType) [node]
 8: 0xebeb3b v8::internal::PrototypeUsers::Add(v8::internal::Isolate*, v8::internal::Handle<v8::internal::WeakArrayList>, v8::internal::Handle<v8::internal::Map>, int*) [node]
 9: 0xe88054 v8::internal::JSObject::LazyRegisterPrototypeUser(v8::internal::Handle<v8::internal::Map>, v8::internal::Isolate*) [node]
10: 0xeb1384 v8::internal::Map::GetOrCreatePrototypeChainValidityCell(v8::internal::Handle<v8::internal::Map>, v8::internal::Isolate*) [node]
11: 0xd68e5c v8::internal::LoadHandler::LoadFromPrototype(v8::internal::Isolate*, v8::internal::Handle<v8::internal::Map>, v8::internal::Handle<v8::internal::JSReceiver>, v8::internal::Handle<v8::internal::Smi>, v8::internal::MaybeObjectHandle, v8::internal::MaybeObjectHandle) [node]
12: 0xd70e67 v8::internal::LoadIC::ComputeHandler(v8::internal::LookupIterator*) [node]
13: 0xd77bcd v8::internal::LoadIC::UpdateCaches(v8::internal::LookupIterator*) [node]
14: 0xd7824c v8::internal::LoadIC::Load(v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Name>) [node]
15: 0xd7cf01 v8::internal::Runtime_LoadIC_Miss(int, unsigned long*, v8::internal::Isolate*) [node]
16: 0x1374fd9  [node]
Aborted (core dumped)

Should I open a bug to V8 regarding this issue?

@devsnek devsnek added the v8 engine Issues and PRs related to the V8 dependency. label Dec 3, 2019
@devsnek
Copy link
Member

devsnek commented Dec 3, 2019

You should report it to V8 (https://crbug.com/v8). If possible, you should also try to get it reproducing without co.

@assaf-xm
Copy link
Author

assaf-xm commented Dec 3, 2019

OK, opened an issue for V8: https://bugs.chromium.org/p/v8/issues/detail?id=10031

@devsnek devsnek closed this as completed Dec 3, 2019
@assaf-xm
Copy link
Author

@devsnek note that the issue was fixed and merged to V8 master: v8/v8@d3a1a5b

When/How it will get into node12?

@targos
Copy link
Member

targos commented Dec 17, 2019

Thanks, I'll reopen the issue since there's a fix to backport.

@targos targos reopened this Dec 17, 2019
targos added a commit to targos/node that referenced this issue Dec 17, 2019
Original commit message:

    [objects] Fix memory leak in PrototypeUsers::Add

    PrototypeUsers::Add now iterates the WeakArrayList to find empty slots
    before growing the array. Not reusing empty slots caused a memory leak.

    It might also be desirable to shrink the WeakArrayList in the future.
    Right now it is only compacted when invoking CreateBlob.

    Also removed unused PrototypeUsers::IsEmptySlot declaration.

    Bug: v8:10031
    Change-Id: I570ec78fca37e8f0c794f1f40846a4daab47c225
    Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1967317
    Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
    Reviewed-by: Igor Sheludko <ishell@chromium.org>
    Commit-Queue: Dominik Inführ <dinfuehr@chromium.org>
    Cr-Commit-Position: refs/heads/master@{#65456}

Refs: v8/v8@d3a1a5b
Fixes: nodejs#30753
@targos
Copy link
Member

targos commented Dec 17, 2019

#31005

@targos targos closed this as completed in 05041d3 Dec 23, 2019
@alex3d
Copy link

alex3d commented Dec 24, 2019

@targos Will it get into node12?

BridgeAR pushed a commit that referenced this issue Jan 3, 2020
Original commit message:

    [objects] Fix memory leak in PrototypeUsers::Add

    PrototypeUsers::Add now iterates the WeakArrayList to find empty slots
    before growing the array. Not reusing empty slots caused a memory leak.

    It might also be desirable to shrink the WeakArrayList in the future.
    Right now it is only compacted when invoking CreateBlob.

    Also removed unused PrototypeUsers::IsEmptySlot declaration.

    Bug: v8:10031
    Change-Id: I570ec78fca37e8f0c794f1f40846a4daab47c225
    Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1967317
    Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
    Reviewed-by: Igor Sheludko <ishell@chromium.org>
    Commit-Queue: Dominik Inführ <dinfuehr@chromium.org>
    Cr-Commit-Position: refs/heads/master@{#65456}

Refs: v8/v8@d3a1a5b
Fixes: #30753

PR-URL: #31005
Reviewed-By: Richard Lau <riclau@uk.ibm.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Rich Trott <rtrott@gmail.com>
targos added a commit that referenced this issue Jan 14, 2020
Original commit message:

    [objects] Fix memory leak in PrototypeUsers::Add

    PrototypeUsers::Add now iterates the WeakArrayList to find empty slots
    before growing the array. Not reusing empty slots caused a memory leak.

    It might also be desirable to shrink the WeakArrayList in the future.
    Right now it is only compacted when invoking CreateBlob.

    Also removed unused PrototypeUsers::IsEmptySlot declaration.

    Bug: v8:10031
    Change-Id: I570ec78fca37e8f0c794f1f40846a4daab47c225
    Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1967317
    Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
    Reviewed-by: Igor Sheludko <ishell@chromium.org>
    Commit-Queue: Dominik Inführ <dinfuehr@chromium.org>
    Cr-Commit-Position: refs/heads/master@{#65456}

Refs: v8/v8@d3a1a5b
Fixes: #30753

PR-URL: #31005
Reviewed-By: Richard Lau <riclau@uk.ibm.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Rich Trott <rtrott@gmail.com>
BethGriggs pushed a commit that referenced this issue Feb 6, 2020
Original commit message:

    [objects] Fix memory leak in PrototypeUsers::Add

    PrototypeUsers::Add now iterates the WeakArrayList to find empty slots
    before growing the array. Not reusing empty slots caused a memory leak.

    It might also be desirable to shrink the WeakArrayList in the future.
    Right now it is only compacted when invoking CreateBlob.

    Also removed unused PrototypeUsers::IsEmptySlot declaration.

    Bug: v8:10031
    Change-Id: I570ec78fca37e8f0c794f1f40846a4daab47c225
    Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1967317
    Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
    Reviewed-by: Igor Sheludko <ishell@chromium.org>
    Commit-Queue: Dominik Inführ <dinfuehr@chromium.org>
    Cr-Commit-Position: refs/heads/master@{#65456}

Refs: v8/v8@d3a1a5b
Fixes: #30753

PR-URL: #31005
Reviewed-By: Richard Lau <riclau@uk.ibm.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Rich Trott <rtrott@gmail.com>
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
v8 engine Issues and PRs related to the V8 dependency.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants