Skip to content

NodeJS generator seems to generate clients with memory leak #625

@olavloite

Description

@olavloite

The NodeJS gapic clients seem to have a memory leak that can be triggered using the following steps:

  1. Open a gapic client.
  2. Execute one simple request.
  3. Close the gapic client.
  4. Repeat.

This issue was first reported for the Spanner hand-written client, but seems to be more of a generic problem with the generated gapic clients.

The following simple application shows the behavior for both PubSub and Spanner. The memory consumption of the application increases with approx 100KB-200KB for each iteration.

index.js

import {InstanceAdminClient} from "@google-cloud/spanner/build/src/v1/instance_admin_client.js";
import {PublisherClient} from "@google-cloud/pubsub/build/src/v1/publisher_client.js"

await main();

async function main() {
    const REPETITIONS = 50;
    console.log(`Running ${REPETITIONS} times`);
    for (let i = 0; i < REPETITIONS; i++) {
        await usePubSubGapic();
        global.gc();
        const used = process.memoryUsage().heapUsed / 1024 / 1024;
        console.log(
            `${i} Current mem usage ${Math.round(used * 100) / 100} MB`
        );
    }
    for (let i = 0; i < REPETITIONS; i++) {
        await useSpannerGapic();
        global.gc();
        const used = process.memoryUsage().heapUsed / 1024 / 1024;
        console.log(
            `${i} Current mem usage ${Math.round(used * 100) / 100} MB`
        );
    }
}

async function useSpannerGapic() {
    const client = new InstanceAdminClient({
        projectId: 'my-project',
        keyFile: '/path/to/key.json',
    });
    await client.listInstanceConfigs({
        parent: 'projects/my-project',
    });
    await client.close();
}

async function usePubSubGapic() {
    const client = new PublisherClient({
        projectId: 'my-project',
        keyFile: '/path/to/key.json',
    });
    await client.listTopics({
        project: 'projects/my-project',
    });
    await client.close();
}

package.json

{
  "type": "module",
  "name": "test-gapic-client",
  "version": "1.0.0",
  "main": "index.js",
  "dependencies": {
    "@google-cloud/pubsub": "^2.8.0",
    "@google-cloud/spanner": "^5.4.0"
  }
}

Output at 50 iterations. Running this script with more iterations and/or with tight memory settings will cause an out of memory error.

Running 50 times
0 Current mem usage 11.7 MB
1 Current mem usage 11.89 MB
2 Current mem usage 12.02 MB
3 Current mem usage 12.21 MB
...
41 Current mem usage 15.84 MB
42 Current mem usage 15.94 MB
43 Current mem usage 16.01 MB
44 Current mem usage 16.09 MB
45 Current mem usage 16.2 MB
46 Current mem usage 16.27 MB
47 Current mem usage 16.37 MB
48 Current mem usage 16.46 MB
49 Current mem usage 16.57 MB

0 Current mem usage 17.01 MB
1 Current mem usage 17.19 MB
2 Current mem usage 17.39 MB
3 Current mem usage 17.53 MB
...
40 Current mem usage 22.58 MB
41 Current mem usage 22.68 MB
42 Current mem usage 22.8 MB
43 Current mem usage 22.93 MB
44 Current mem usage 23.06 MB
45 Current mem usage 23.19 MB
46 Current mem usage 23.34 MB
47 Current mem usage 23.48 MB
48 Current mem usage 23.57 MB
49 Current mem usage 23.85 MB

Metadata

Metadata

Labels

🚨This issue needs some love.priority: p1Important issue which blocks shipping the next release. Will be fixed prior to next release.type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions