Skip to content

Memory leak in the "no-unsupported-features" rule #1717

New issue

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

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

Already on GitHub? Sign in to your account

Closed
2 tasks done
bponomarenko opened this issue Nov 17, 2021 · 4 comments · Fixed by #1718
Closed
2 tasks done

Memory leak in the "no-unsupported-features" rule #1717

bponomarenko opened this issue Nov 17, 2021 · 4 comments · Fixed by #1718
Labels

Comments

@bponomarenko
Copy link

bponomarenko commented Nov 17, 2021

Checklist

  • I have tried restarting my IDE and the issue persists.
  • I have read the FAQ and my problem is not listed.

Tell us about your environment

  • ESLint version: 7.32.0
  • eslint-plugin-vue version: 7.20.0
  • Node version: 14.16.0
  • Operating System: macOS Catalina 10.15.7

Some additional details:

  • My project is relatively big – around 3000 *.vue files and around 2000 of *.js files with // @vue/component comment

Please show your full configuration:

{
    "root": true,
    "env": { "es2021": true },
    "plugins": ["vue"],
    "extends": ["plugin:vue/recommended"],
    "rules": {
        "vue/no-unsupported-features": ["error", { "version": "^2.6.14" }]
    }
}

Note this is not full .eslintrc file, but just relevant part with the configured rule in question

What did you do?

No code here because this issue can be reproduced with both valid and invalid code.

What did you expect to happen?
Memory consumption does not significantly change when no-unsupported-features rule is enabled.

What actually happened?

ESLint output is not relevant here, as we need to look into "Activity Monitor" instead.

With the rule enabled, during the lint process (which we run as eslint --ext .js,.vue .) RAM consumption keeps raising and peaks at to 3.5G-4Gb level. When I disable the rule – it doesn't go more than 800-900Mb. I tried to disable other rules, but it seems this is the one which causes the issue.

I tried to debug it myself and I narrowed it down to this line:

/** @type {Map<VElement, StyleVariablesContext>} */
const cache = new Map()

This file is used in the style-css-vars-injection syntax spec, which is part of the no-unsupported-features rule.
From my understanding, this cache is created globally per entire lint process, while it would be populated with values from each of the scanned files. This cache uses VElement objects as a key, which makes them "trapped" in this cache for the duration of the entire lint process. As a result Node.js cannot garbage collect those references when scan for individual file is done.

Simple change to WeakMap seems to be solving the problem:

/** @type {WeakMap<VElement, StyleVariablesContext>} */
const cache = new WeakMap()

Btw during my experiments, I noticed that part of that code that reads from the cache is never executed. I'm not sure what is the use case for this cache implementation, but for now it seems redundant for me and it could be removed altogether.

Repository to reproduce this issue

I'm not sure if you still need it, but I can add it if you confirm.

@ota-meshi ota-meshi added the bug label Nov 18, 2021
@ota-meshi
Copy link
Member

Thank you for finding the cause!

@bponomarenko
Copy link
Author

@ota-meshi Thanks for the quick fix!

Unfortunately I found another memory leak in the another rule. Will report it later today.

@bponomarenko
Copy link
Author

@ota-meshi That another rule with memory leak is no-unused-properties, but it seems the cause is exactly the same – it also uses style-variables utility. So the fix you did already should be enough. Thanks again.

@ota-meshi
Copy link
Member

Thanks for letting me know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants