-
-
Notifications
You must be signed in to change notification settings - Fork 488
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
fix: memory leak #2616
fix: memory leak #2616
Conversation
Wow, I just found the same cause and wanted to report it! 😂 Good thing this PR was a bit quicker than me 😉 I'll try it in my project now. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tried and it seems to resolve the issue! ❤️
There seems to be another leak in some head / pinia related files in my project though 😅 but that's unrelated to nuxt-i18n.
That's amazing work! ❤️ The causing of memory leaks is very difficult since the code must be checked.
As far as I know, I think you can control GC in Javascript by using https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/FinalizationRegistry However, unlike C# and other languages, JavaScript does not currently provide a mechanism to release resources like the dispose / descructor pattern. Once again, thank you so much! |
@dargmuesli
@kazupon |
* fix: `nuxtI18nOptions` being set and not cleaned up * fix: use local `useNuxtApp` instead of passing nuxt context as argument * fix: remove `nuxtI18nOptions` copy
🔗 Linked issue
❓ Type of change
📚 Description
It is unlikely that this fixes all present memory leaks in the module, but this small change appears to have a measurable impact on the memory usage.
I ran the reproductions with the latest release
rc.9
, and took memory snapshots with chrome. First without any requests, then runningsiege
for 10 seconds with 10 concurrent users (siege -t 10s -c 10 "http://localhost:3000/"
) after which I took another snapshot. After waiting for a short moment I took another snapshot in case any more memory was cleared 🤷♂️. Then I installed my local modified@nuxtjs/i18n
and went through the same steps.My testing isn't exactly thorough, but it was a reliable way to see the memory usage go up and stay up, it's possible memory will still increase after longer usage and uptime, it's something that takes time and patience.
Below a comparison of the snapshots before and after installing the modified package:
I also tested #2034 (comment) (or https://github.com/danielroe/i18n-memory-leak) after making this comparison image, memory usage went from ~121mb to ~33mb.
While profiling I kept seeing
nuxtI18Options
andbaseUrl
, based on thismy theory is that the nuxt context is not being disposed of correctly as it is being set onnuxtI18nOptions
in thei18n.ts
plugin.For example here:
i18n/src/runtime/plugins/i18n.ts
Lines 86 to 91 in 4bf4f50
nuxtI18nOptions.baseUrl
is being set to a function returned fromextendBaseUrl
, the returned function makes use of the passed nuxt context (options.nuxt
),nuxtI18nOptions
is not defined in the scope of the plugin so I can imagine it would be hard to know when to dispose/free the memory? Based on this assumption I instead create a new object usingnuxtI18nOptions
, which since it's scoped to the plugin should be easier to safely dispose/free.I don't know enough about memory management or garbage collection in Javascript, but I have experience optimizing memory usage for mobile games in C#, to provide a background for my reasoning. If someone has good resources on this please share them so I can form more informed conclusions 😅
Update
Based on the testing I did, I changed the way the Nuxt context is used/retrieved. Instead of passing it to functions/closures and potentially causing leaks the
useNuxtApp
composable is used where possible.There is still a small and slow increase in memory usage for every few 1000s of requests, will look into that as well.
📝 Checklist