Skip to content
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

Memory Leak #281

Open
agracia-foticos opened this issue Nov 28, 2023 · 20 comments
Open

Memory Leak #281

agracia-foticos opened this issue Nov 28, 2023 · 20 comments

Comments

@agracia-foticos
Copy link

Environment

  • Operating System: Linux
  • Node Version: v20.5.1
  • Nuxt Version: 3.8.2
  • CLI Version: 3.10.0
  • Nitro Version: 2.8.0
  • Package Manager: [email protected]
  • Builder: -
  • User Config: -
  • Runtime Modules: -
  • Build Modules: -

Reproduction

image

When i crawled our web, crashes by memory leak

Describe the bug

image

When i crawled our web, crashes by memory leak

Additional context

No response

Logs

No response

@harlan-zw
Copy link
Collaborator

Will need some reproduction details

@agracia-foticos
Copy link
Author

Will need some reproduction details

We have a lot of code generated, it is impossible to have a minimal playback environment

@harlan-zw
Copy link
Collaborator

harlan-zw commented Nov 28, 2023

Without a reproduction, there isn't much I can do.

This screenshot just shows it hit a memory limit while running this line, which doesn't mean that's where a memory leak is.

There's no way to confirm if Unhead is the problem or if downstream code implementing it, which seems more likely given this is the first time a memory leak issue has been opened and knowing how the API is designed.

@dargmuesli
Copy link
Contributor

dargmuesli commented Dec 13, 2023

There could be some truth to this report. As you know, @harlan-zw, I'm new to debugging memory overflows, but poking around led me to the function

export function createHeadCore<T extends {} = Head>(options: CreateHeadOptions = {}) {

in which there are two suspects: const updated and const head. Both refer to each other and it seems that could create a loop which might prevent associated resources from being garbage collected.
Would that make sense?

@BobbieGoede
Copy link

While testing for memory leaks in @nuxtjs/i18n it did seem like something was leaky and I suspected unhead, but I haven't been able to consistently reproduce it.

Whatever seemed to be leaking did so at a low rate, unless someone manages to reproduce it, I wouldn't worry too much about it. 😅

@harlan-zw
Copy link
Collaborator

Thank you for your investigation @BobbieGoede! Some great work on @nuxtjs/i18n 👏

@dargmuesli
Copy link
Contributor

I investigated too 😭 😂 I have one or two other theories on suspect code, maybe we can have a look together in the coming days @harlan-zw or @BobbieGoede? If you have time next week, we could meet on Discord to stop the leak 🧹

@dargmuesli
Copy link
Contributor

Just saw and tested that nuxt-modules/i18n#2621 is also a great fix 🔥 🚀 From the looks it seems that the only directly noticeable leak left is on me in my project. So no need for a call rn, but I may get back to that if I find anything else. Thank you all for the good work!

@MosheL
Copy link

MosheL commented Jan 15, 2024

I can explain better than the opener of the bug. He is right.
I was wasted a day to debug a similar bug in my code, so I can explain better.

The leak is in the $vm._ of vue, persisted in node memory by the global __unhead_injection_handler__ and its friends, so after the SSR page go down, the memory is not freed and stayed in memory again and again.

image

@harlan-zw
Copy link
Collaborator

There should only be a single instance of Vue kept in memory, it's not freed as you correctly identified.

It shouldn't be stacking though, your screenshot doesn't show that it is afaik?

@BobbieGoede
Copy link

BTW, while I was searching for what could be leaking memory in the i18n module I often saw this pattern (Symbol(__DEV__ ? 'LIB_KEY_HERE' : '') which obscures/removes the identifying global key in a production build.

I guess the primary reason for doing this is to reduce the build size, but a side effect is that we don't see these keys when debugging memory (which I have only done on a production build). Since unhead does not use this pattern, and it uses some memory, it will be one of the first things you'll see when debugging which doesn't necessarily mean that it is leaking.

@obulat
Copy link

obulat commented Jan 25, 2024

This seems to be one of the largest memory leaks that's preventing us at Openverse from migrating to Nuxt 3. Even after I removed all of the useHead calls, only leaving the head properties in the nuxt.config.ts, I can see a lot of retained dependencies of $head:

Screenshot 2024-01-25 at 6 08 59 PM

Here's the PR for migrating to Nuxt 3 that is, unfortunately, unusable, due to memory leaks.

@harlan-zw
Copy link
Collaborator

harlan-zw commented Jan 25, 2024

Looks like a vue-router stack? $head is a singleton on the vue VM (like globalProperties), so not sure what you're showing here exactly.

Not to say there isn't an issue, but this doesn't help me identify anything from Unhead's side.

Also, see comment above.

This is something I do want to take a deeper look into in any case but I'm currently limited with time so unless more people are reporting memory leak issues with Nuxt / Unhead then it's a low priority as it's going to be a lengthy investigation.

@BobbieGoede
Copy link

@obulat
Also I see you're using @nuxtjs/i18n, I recommend installing the edge version with pnpm i -D @nuxtjs/i18n@npm:@nuxtjs/i18n-edge, the latest changes include a fix for a memory leak.

This won't fix the memory leak in your PR (I checked) but likely reduces it, it could still be the i18n module or unhead or both, I'll look into it some more when I have the time.

@obulat
Copy link

obulat commented Jan 25, 2024

@obulat
Also I see you're using @nuxtjs/i18n, I recommend installing the edge version with pnpm i -D @nuxtjs/i18n@npm:@nuxtjs/i18n-edge, the latest changes include a fix for a memory leak.

This won't fix the memory leak in your PR (I checked) but likely reduces it, it could still be the i18n module or unhead or both, I'll look into it some more when I have the time.

Thank you for looking into our repo, @BobbieGoede ! I'll try the edge version.

@harlan-zw
Copy link
Collaborator

harlan-zw commented Mar 4, 2024

I did some testing with clinic.js and was not able to replicate any sort of memory leak.

image

This is with ~500 connections doing ~5k requests x2 on a Nuxt app.

Will leave this issue open in case anyone has any further research they can share. (I tried testing with other clinic.js tools but it was failing).

@Rigo-m
Copy link

Rigo-m commented Oct 15, 2024

image
I am too having problems with __unhead_injection_handler__ retaining a lot of stuff.
(Nuxt v3.13.2, both trying to use i18n and i18n-micro).

@Rigo-m
Copy link

Rigo-m commented Oct 15, 2024

Also I see many strings not getting garbage collected, megs and megs of ram not being cleared. Up for a call if you want to check this out @harlan-zw

@daniluk4000
Copy link
Contributor

Also I see many strings not getting garbage collected, megs and megs of ram not being cleared. Up for a call if you want to check this out @harlan-zw

Can you include reproduction? On our large project with heavy unhead usage (including not-so-official solutions in our plugins) our memory stays at ~400MB without significant increases. I also noticed unhead growing in size, but GC seems to be working for us

@Tofandel
Copy link

To anyone experiencing this issue, I would ask that you check in your package-lock.json or yarn.lock that your vue is up to date, (it might not be because of a bug in yarn that does not update sub deps when targeting update of a single package so if only nuxt is a direct dep and is targeted for upgrade, vue will not upgrade)

Please check that you are at least on 3.5.7 which fixes 3 memory leak issues, and if you are not, then please try again after upgrading and report back
https://github.com/vuejs/core/blob/main/CHANGELOG.md#357-2024-09-20

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

No branches or pull requests

9 participants