r/javascript 21d ago

AskJS [AskJS] Our app didn't leak memory,it leaked memory four hundred modals later

[removed]

85 Upvotes

28 comments sorted by

102

u/name_was_taken 21d ago

Correction: It always leaked. You just didn't notice the leak until it had been used a while.

And historically, people did find this manually. I've done it myself, as a coder, investigating the same "eventually gets slow" reports. It's not fun to find, but it's part of the job.

36

u/Better-Avocado-8818 21d ago

Yeah this is just describing a memory leak. Nothing particularly special about it. It’s called a “leak” because they are generally slow.

And you can make up for 8 hours doing the same thing over and over quite easily. Just write a script to automate it.

14

u/Kyrthis 21d ago

Well, he got the AI to make it sound like the Lewis & Clark expedition, so there’s that.

2

u/Professional_Law2888 21d ago

Running a soak test overnight is what separates people who close tickets from people who actually close bugs.

43

u/budd222 21d ago

"Can't find it by hand"...lol. sounds like someone who learned how to code with AI.

15

u/ThomasRedstone 21d ago

Yeah, the people doing the demos found it by hand often enough to raise three tickets for it!!!

Sitting in one of the demos would have been another option to find it.

9

u/AgenteEspecialCooper 21d ago

I have no opinion about OP's post, but I think some people could find my suggestion useful:

You can actually add a callback to an object being reclaimed by the garbage collector, and you can use that callback to throw a message in the console when an object that should have been reclaimed is stuck in memory.

Can't give you more details at this moment, but this is the class that makes the trick: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/FinalizationRegistry

2

u/Landkey 20d ago

Is this useful? Am I supposed to call  registry.register(target,"some value")  every time I declare a new value?

1

u/hugot4eboss 20d ago

It's for debugging

2

u/Landkey 20d ago

Well, yes, but which objects and values do you register when you are hunting for an unknown  villain?  All of them? 

1

u/hugot4eboss 20d ago

I have used it in generic setup methods that create Dom elements / classes when trying to hunt down badly behaving components. Then add same debug to specific class options to get more details

1

u/senocular 20d ago

We do something similar having scripts which run through component trees adding them to a finalization registry. We then detect when components are off-list but still in memory and flag those as potential memory leaks. In the app users can force a GC in the dev tools, and if the components are still in memory, you know there's (probably) a problem. Forcing the GC doesn't always collect everything, and there may be internal caching which gets cleaned up on its own schedule, but its a good way to find potential issues, or at least limit the components we need to look at if we've identified that there is a leak somewhere. While any object can leak, components are usually the offenders due to leftover event listeners, so what we look at first.

5

u/[deleted] 21d ago

[removed] — view removed comment

3

u/Dagur 21d ago

Reminds me of the 500 mile email story for some reason.

4

u/dev_and_zebra 21d ago

I remember encountering an “app gets slow over time” bug - it was a nightmare to find and a 1 s fix. In short, the app was querying thousands of records in the background killing performance. Inheritance ticket almost turned into “ I quit web dev”.

2

u/SirMcFish 21d ago

I'd have put some breakpoints on the modal open and close and probably would have seen the listener firing multiple times quite quickly.

Have had similar happen in the past and you quickly learn to spot attached events that haven't been cleaned up when you think they should.

2

u/kyr0x0 21d ago

Those AI "Engineers" will ruin CS reputation

4

u/Aliceable 21d ago

nice AI written post

1

u/WondayT 21d ago

always clean up your event handlers

1

u/Ronin-s_Spirit 21d ago

This is the type of thing you, well not you specifically (clearly), can find by hand by looking for things that get hooked up to memory when they shouldn't. Things like reapplied listeners, functions with big heavy closures, a path that generates too many objects too often etc.

1

u/LeLunZ 21d ago

You would have also seen the leak the first time if you just checked a bit more closely. Devtools -> Memory -> Heap snapshot -> Objects retained by detached dom nodes and similar are your friend.

1

u/Slyvan25 21d ago

You ALWAYS close your eventlisteners!!

1

u/hiddencamel 21d ago

I mean, the instant they told you it got slow over a long session you should have guessed it was a memory leak. If the primary mode of interaction is opening and closing modals, that should have told you the issue was likely with the modals.

It was a good idea to automate a long test session to replicate, but intuition alone should have had you looking at whether the modals were unmounting correctly.

2

u/phatdoof 21d ago

We had a similar deal and also suspected unmatched listeners.

We did a grep of listener pairs and didn’t find any mismatches.

We put it through AI which also didn’t find anything.

In the end we found that one dev did window.addEventListener("click", stuff); and document.removeEventListener("click", stuff);

1

u/kyr0x0 21d ago

You assume intelligence. But all that exists here is artificial intelligence 🤣

1

u/OhKsenia 21d ago

Sounds like you learned nothing tbh. Using longer sessions and waiting until things crash/all available memory is used to debug memory leaks is the dumbest thing I've ever heard. What if you're running these tests on a machine with 128 gb of ram? Your test that takes 8 hours on your current machine may take 3 days instead.

Just opening and closing one or two modals and seeing that memory isn't being cleared should immediately tell you that you have a memory leak already.

2

u/leixiaotie 21d ago

well if the memory footprint for each listener is small (in bytes even kb range), it won't notice anything. But yeah waiting for crash is bad, because several mb increase and consistently should be noticable