Subject: Re: bug#79023: 30.1.90; Suspicion of memory leak on internal_redisplay (MacOS)

From: Przemysław Alexander Kamiński<[email-masked]>
Date: Wed, 23 Jul 2025 17:00:31 +0200

On 22 Jul 2025, at 1:33, Rudolf Adamkovič wrote:
> P.S. The remaining 5.22 - 5.13 ~= 100 MB is wasted due to bugs elsewhere.

I found the source and I don't like it. Spoiler alert: it's [NSApp run] invocations.

Critical functions/methods (ns_select_1/ns_read_socket_1) are draining the events in the run loop by calling [NSApp run].
As far as I understand ns_select_1 should be replacement for Linux' pselect, so why it calls run is puzzling at least.

Because of this calls in  many different things are happening. ns_select_1 might or might not release outerpool but events processing inside these loops still can try to allocate fonts, menus and all kinds of data. Which should be deallocated, but some objects are made for deallocation on Lisp and not handled.

But the worst thing I found is that there are hundreds of immediatelly killed CGContext's etc. Why? In cases where pool draining DOES happen the inner application gets a clean slate and rebuilds from scratch all view objects be able to process event queue.  So even if autoreleased a single ns_select_1 spawn might cause a 6mb allocation while creating IOSurface andredisplaying and redrawing even though it's never used.

I figured that maybe never reinitializing the autorelease pool during runloop would help, but I found that internal mechanism for processing Emacs Event rellies on modifying the current event in the processing queue... (which should be empty sometimes on autoinitialize, but since events come at rapid rate, this is not guaranteed). That results in events modified. I think that bug I observed, where Emacs was hanging on ns_select_1 could be the reason - interrupt happened but the interrupt was rewritten to emacs_event and here we go. It would also explain small annoyances, microhangs, lack of responsiveness etc.

After multiple attempts I finally found something that works - made a simple lock on layout rendering which seems to keep things in check (note that discarded events are pointless anyway, because those discarded ones would trigger on re-allocated instance so not visible anyway).

This patch has downside of making resize "weird".

Best,
Przemysław Alexander Kamiński