GNU bug report logs - #79023
30.1.90; Suspicion of memory leak on internal_redisplay (MacOS)

Previous Next

Package: emacs;

Reported by: Przemysław Alexander Kamiński <przemyslaw <at> kaminski.se>

Date: Tue, 15 Jul 2025 07:14:01 UTC

Severity: normal

Found in version 30.1.90

To reply to this bug, email your comments to 79023 AT debbugs.gnu.org.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#79023; Package emacs. (Tue, 15 Jul 2025 07:14:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Przemysław Alexander Kamiński <przemyslaw <at> kaminski.se>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Tue, 15 Jul 2025 07:14:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Przemysław Alexander Kamiński
 <przemyslaw <at> kaminski.se>
To: bug-gnu-emacs <at> gnu.org
Subject: 30.1.90; Suspicion of memory leak on internal_redisplay (MacOS)
Date: Tue, 15 Jul 2025 09:12:47 +0200
[Message part 1 (text/plain, inline)]
Hi,

it seems there's some memory leak happening in redisplay_internal
function.

I've noticed that over time Emacs become slower and slower. After 2-3
hours bug is noticable. Total - as reported by OS - usage is >2Gb. GC is
working correctly and running it manually didn't change anything. Memory
report marks only ~50mb, and total memory on relatively fresh instance
is ~500mb. I've noticed that at approx 3Gb I start receiving "freezes of 
doom".

Previously I suspected vterm but I don't use vterm much if any.

Can't say anything more, if there's anything else I could try to
debug/report let me know.

Best,
Przemysław Alexander Kamiński

---

In GNU Emacs 30.1.90 (build 1, aarch64-apple-darwin24.5.0, NS
 appkit-2575.60 Version 15.5 (Build 24F74)) of 2025-06-20 built on 
omega
Windowing system distributor 'Apple', version 10.3.2575
System Description:  macOS 15.5

Configured using:
 'configure --disable-dependency-tracking --disable-silent-rules
 --enable-locallisppath=/opt/homebrew/share/emacs/site-lisp
 --infodir=/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/info/emacs
 --prefix=/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5
 --with-native-compilation=aot --with-xml2 --with-gnutls
 --without-compress-install --without-dbus --without-imagemagick
 --with-modules --with-rsvg --with-webp --with-ns
 --disable-ns-self-contained 'CFLAGS=-g -Og -O2 -DFD_SETSIZE=10000
 -DDARWIN_UNLIMITED_SELECT -I/opt/homebrew/opt/sqlite/include
 -I/opt/homebrew/opt/gcc/include -I/opt/homebrew/opt/libgccjit/include'
 'LDFLAGS=-L/opt/homebrew/opt/sqlite/lib -L/opt/homebrew/lib/gcc/15
 -I/opt/homebrew/opt/gcc/include 
-I/opt/homebrew/opt/libgccjit/include''

Configured features:
ACL GIF GLIB GMP GNUTLS JPEG LCMS2 LIBXML2 MODULES NATIVE_COMP NOTIFY
KQUEUE NS PDUMPER PNG RSVG SQLITE3 THREADS TIFF TOOLKIT_SCROLL_BARS
TREE_SITTER WEBP XIM ZLIB

Important settings:
  value of $LC_ALL: en_US.UTF-8
  value of $LC_CTYPE: pl_PL.UTF-8
  value of $LANG: en_US.UTF-8
  locale-coding-system: utf-8

Major mode: Lisp Interaction

Minor modes in effect:
  global-git-commit-mode: t
  magit-auto-revert-mode: t
  aggressive-indent-mode: t
  paren-face-mode: t
  paredit-mode: t
  display-line-numbers-mode: t
  delete-selection-mode: t
  repeat-mode: t
  recentf-mode: t
  global-org-modern-mode: t
  async-bytecomp-package-mode: t
  winner-mode: t
  server-mode: t
  corfu-history-mode: t
  corfu-popupinfo-mode: t
  global-corfu-mode: t
  corfu-mode: t
  which-key-mode: t
  minions-mode: t
  vertico-mode: t
  display-time-mode: t
  adaptive-wrap-prefix-mode: t
  savehist-mode: t
  general-override-mode: t
  override-global-mode: t
  tooltip-mode: t
  global-eldoc-mode: t
  eldoc-mode: t
  show-paren-mode: t
  electric-indent-mode: t
  mouse-wheel-mode: t
  menu-bar-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  undelete-frame-mode: t
  minibuffer-regexp-mode: t
  line-number-mode: t
  visual-line-mode: t
  transient-mark-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  abbrev-mode: t

Load-path shadows:
/Users/xlii/.emacs.d/elpa/emacsql-sqlite-builtin-20240825.1837/emacsql-sqlite-builtin 
hides 
/Users/xlii/.emacs.d/elpa/emacsql-20250601.1009/emacsql-sqlite-builtin
/Users/xlii/.emacs.d/elpa/which-key-20240620.2145/which-key hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/which-key
/Users/xlii/.emacs.d/elpa/transient-20250701.1223/transient hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/transient
/Users/xlii/.emacs.d/elpa/modus-themes-20250710.1713/theme-loaddefs 
hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/theme-loaddefs
/Users/xlii/.emacs.d/elpa/elixir-ts-mode-20241228.919/elixir-ts-mode 
hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/progmodes/elixir-ts-mode
/Users/xlii/.emacs.d/elpa/heex-ts-mode-20250511.643/heex-ts-mode hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/progmodes/heex-ts-mode
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-comint hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-comint
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-exp hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-exp
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-ctags hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-ctags
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-emacs-lisp hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-emacs-lisp
/Users/xlii/.emacs.d/elpa/org-9.7.31/oc hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/oc
/Users/xlii/.emacs.d/elpa/org-9.7.31/ox-texinfo hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ox-texinfo
/Users/xlii/.emacs.d/elpa/org-9.7.31/ol-irc hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ol-irc
/Users/xlii/.emacs.d/elpa/org-9.7.31/ol-doi hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ol-doi
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-refile hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-refile
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-version hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-version
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-num hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-num
/Users/xlii/.emacs.d/elpa/org-9.7.31/ol-mhe hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ol-mhe
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-shell hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-shell
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-attach hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-attach
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-C hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-C
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-macs hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-macs
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-entities hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-entities
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-dot hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-dot
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-sql hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-sql
/Users/xlii/.emacs.d/elpa/org-9.7.31/ol-eww hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ol-eww
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-datetree hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-datetree
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-macro hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-macro
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-eval hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-eval
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-haskell hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-haskell
/Users/xlii/.emacs.d/elpa/org-9.7.31/ox-org hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ox-org
/Users/xlii/.emacs.d/elpa/org-9.7.31/ol-rmail hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ol-rmail
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-awk hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-awk
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-groovy hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-groovy
/Users/xlii/.emacs.d/elpa/org-9.7.31/ox-icalendar hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ox-icalendar
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-octave hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-octave
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-scheme hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-scheme
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-mobile hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-mobile
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-processing hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-processing
/Users/xlii/.emacs.d/elpa/org-9.7.31/oc-biblatex hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/oc-biblatex
/Users/xlii/.emacs.d/elpa/org-9.7.31/oc-csl hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/oc-csl
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-colview hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-colview
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-R hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-R
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-table hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-table
/Users/xlii/.emacs.d/elpa/org-9.7.31/ox-html hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ox-html
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-fortran hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-fortran
/Users/xlii/.emacs.d/elpa/org-9.7.31/ol hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ol
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-plantuml hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-plantuml
/Users/xlii/.emacs.d/elpa/org-9.7.31/ol-docview hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ol-docview
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-perl hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-perl
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-sqlite hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-sqlite
/Users/xlii/.emacs.d/elpa/org-9.7.31/oc-basic hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/oc-basic
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-sed hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-sed
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-fold-core hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-fold-core
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-ditaa hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-ditaa
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-ruby hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-ruby
/Users/xlii/.emacs.d/elpa/org-9.7.31/oc-bibtex hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/oc-bibtex
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-habit hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-habit
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-loaddefs hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-loaddefs
/Users/xlii/.emacs.d/elpa/org-9.7.31/ol-gnus hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ol-gnus
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-screen hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-screen
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-mouse hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-mouse
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-css hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-css
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-inlinetask hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-inlinetask
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-lisp hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-lisp
/Users/xlii/.emacs.d/elpa/org-9.7.31/ol-eshell hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ol-eshell
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-pcomplete hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-pcomplete
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-lint hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-lint
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-id hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-id
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-capture hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-capture
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-sass hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-sass
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-tangle hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-tangle
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-calc hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-calc
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-java hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-java
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-compat hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-compat
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-attach-git hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-attach-git
/Users/xlii/.emacs.d/elpa/org-9.7.31/ox-beamer hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ox-beamer
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-protocol hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-protocol
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-element hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-element
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-lob hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-lob
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-tempo hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-tempo
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-python hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-python
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-latex hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-latex
/Users/xlii/.emacs.d/elpa/org-9.7.31/ol-w3m hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ol-w3m
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-agenda hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-agenda
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-persist hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-persist
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-ocaml hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-ocaml
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-ref hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-ref
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-fold hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-fold
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-julia hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-julia
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-lilypond hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-lilypond
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-table hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-table
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-clojure hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-clojure
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-indent hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-indent
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-plot hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-plot
/Users/xlii/.emacs.d/elpa/org-9.7.31/ox-latex hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ox-latex
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-src hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-src
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-duration hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-duration
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-makefile hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-makefile
/Users/xlii/.emacs.d/elpa/org-9.7.31/ol-info hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ol-info
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-clock hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-clock
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-forth hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-forth
/Users/xlii/.emacs.d/elpa/org-9.7.31/ox-odt hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ox-odt
/Users/xlii/.emacs.d/elpa/org-9.7.31/ol-man hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ol-man
/Users/xlii/.emacs.d/elpa/org-9.7.31/ox-publish hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ox-publish
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-archive hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-archive
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-org hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-org
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-lua hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-lua
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-keys hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-keys
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-eshell hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-eshell
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-faces hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-faces
/Users/xlii/.emacs.d/elpa/org-9.7.31/ox-man hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ox-man
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-list hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-list
/Users/xlii/.emacs.d/elpa/org-9.7.31/ox-md hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ox-md
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-goto hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-goto
/Users/xlii/.emacs.d/elpa/org-9.7.31/ol-bbdb hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ol-bbdb
/Users/xlii/.emacs.d/elpa/org-9.7.31/org hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org
/Users/xlii/.emacs.d/elpa/org-9.7.31/ol-bibtex hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ol-bibtex
/Users/xlii/.emacs.d/elpa/org-9.7.31/ox-koma-letter hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ox-koma-letter
/Users/xlii/.emacs.d/elpa/org-9.7.31/ox-ascii hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ox-ascii
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-matlab hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-matlab
/Users/xlii/.emacs.d/elpa/org-9.7.31/ox hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ox
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-timer hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-timer
/Users/xlii/.emacs.d/elpa/org-9.7.31/oc-natbib hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/oc-natbib
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-core hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-core
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-feed hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-feed
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-gnuplot hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-gnuplot
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-js hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-js
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-element-ast hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-element-ast
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-footnote hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-footnote
/Users/xlii/.emacs.d/elpa/org-9.7.31/ob-maxima hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/ob-maxima
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-cycle hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-cycle
/Users/xlii/.emacs.d/elpa/org-9.7.31/org-crypt hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/org/org-crypt
/Users/xlii/.emacs.d/elpa/eldoc-1.16.0/eldoc hides 
/opt/homebrew/Cellar/emacs-plus <at> 30/HEAD-a2bfce5/share/emacs/30.1.90/lisp/emacs-lisp/eldoc

Features:
(shadow sort mail-extr autothemer git-msg-prefix git-ps1-mode
magit-bookmark magit-submodule magit-blame magit-stash magit-reflog
magit-bisect magit-push magit-pull magit-fetch magit-clone magit-remote
magit-commit magit-sequence magit-notes magit-worktree magit-tag
magit-merge magit-branch magit-reset magit-files magit-refs magit-status
magit magit-repos magit-apply magit-wip magit-log which-func magit-diff
smerge-mode diff git-commit log-edit pcvs-util add-log magit-core
magit-autorevert autorevert magit-margin magit-transient magit-process
with-editor magit-mode transient benchmark magit-git magit-base
magit-section crm plantuml-mode deflate string-inflection emacsbug
message yank-media rfc822 mml mml-sec epa gnus-util mm-decode mm-bodies
mm-encode mailabbrev gmm-utils mailheader sendmail mail-utils
vertico-sort cursor-sensor vc-git diff-mode track-changes vc-dispatcher
go-mode find-file etags fileloop expand-region text-mode-expansions
cc-mode-expansions the-org-mode-expansions python-el-fgallina-expansions
js-mode-expansions er-basic-expansions expand-region-core
expand-region-custom aggressive-indent lisp-mnt paren-face paredit
display-line-numbers delsel cus-load em-hist esh-mode esh-var
ghub-legacy ghub-graphql treepy gsexp ghub url-http mail-parse rfc2231
rfc2047 rfc2045 mm-util ietf-drums mail-prsvr url-gw url-auth llama
gnutls dashboard dashboard-widgets rect ffap all-the-icons
all-the-icons-faces data-material data-weathericons data-octicons
data-fileicons data-faicons data-alltheicons repeat affe js c-ts-common
cc-mode cc-fonts cc-guess cc-menus cc-cmds cc-styles cc-align cc-engine
cc-vars cc-defs flycheck-clj-kondo flycheck jka-compr let-alist
consult-lsp lsp lsp-mode lsp-protocol xref spinner network-stream nsm
markdown-mode edit-indirect imenu ht filenotify ewoc epg rfc6068
epg-config recentf tree-widget consult bookmark pp ob-latex ob-clojure
ob-prolog prolog align ob-sql ob-restclient restclient ob-python python
project ob-dot ob-ruby ob-plantuml ob-shell org-tempo tempo org-crypt
ob-js ox-md ox-odt rng-loc rng-uri rng-parse rng-match rng-dt rng-util
rng-pttrn nxml-parse nxml-ns nxml-enc xmltok nxml-util ox-latex
ox-icalendar org-agenda ox-html table ox-ascii ox-publish ox org-attach
org-element org-persist xdg org-id org-refile org-element-ast inline
avl-tree org-protocol f org-modern async-bytecomp async winner
ayu-grey-theme ls-lisp server corfu-history corfu-popupinfo corfu
which-key minions free-keys axk:toggle-truncate vertico-reverse
vertico-repeat vertico-quick vertico cape-keyword dash eat term
disp-table ehelp shell ediff ediff-merg ediff-mult ediff-wind ediff-diff
ediff-help ediff-init ediff-util dired dired-loaddefs delight time
shrface compile org ob ob-tangle ob-ref ob-lob ob-table ob-exp org-macro
org-src sh-script smie treesit executable ob-comint org-pcomplete
org-list org-footnote org-faces org-entities time-date ob-emacs-lisp
ob-core ob-eval org-cycle org-table ol org-fold org-fold-core org-keys
oc org-loaddefs thingatpt find-func cal-menu calendar cal-loaddefs
org-version org-compat org-macs shr text-property-search pixel-fill
kinsoku url-file puny svg xml dom sqlformat reformatter hideshow
noutline outline adaptive-wrap cape comp comp-cstr comp-run comp-common
dabbrev orderless compat savehist visual-regexp avy-zap avy swiper ivy
ivy-faces colir edmacro kmacro warnings memoize hydra lv s polymode
derived poly-lock polymode-base polymode-weave polymode-export
polymode-compat advice polymode-methods polymode-core format-spec
polymode-classes eieio-custom wid-edit eieio-base color general cl-extra
help-mode cl-libify cl exec-path-from-shell eshell esh-cmd generator
esh-ext esh-opt esh-proc esh-io esh-arg pcomplete comint ansi-osc
ansi-color ring esh-module esh-module-loaddefs esh-util files-x
use-package use-package-ensure use-package-delight use-package-diminish
use-package-bind-key bind-key use-package-core rx ace-window-autoloads
ack-autoloads adaptive-wrap-autoloads affe-autoloads
aggressive-indent-autoloads all-the-icons-autoloads
atomic-chrome-autoloads avy-zap-autoloads awk-ts-mode-autoloads
ayu-theme-autoloads base16-theme-autoloads browse-at-remote-autoloads
cape-autoloads capf-autosuggest-autoloads cfrs-autoloads
chatgpt-shell-autoloads citre-autoloads cl-libify-autoloads
clips-mode-autoloads clj-refactor-autoloads cider-autoloads
clojure-mode-autoloads color-theme-sanityinc-tomorrow-autoloads
company-quickhelp-autoloads company-autoloads consult-dash-autoloads
consult-flycheck-autoloads consult-lsp-autoloads
consult-projectile-autoloads consult-yasnippet-autoloads
copy-as-format-autoloads corfu-candidate-overlay-autoloads
corfu-prescient-autoloads corfu-autoloads coterm-autoloads
counsel-autoloads csv-mode-autoloads cue-mode-autoloads
cyberpunk-theme-autoloads d2-mode-autoloads dash-docs-autoloads
dashboard-autoloads datetime-autoloads dedicated-autoloads
delight-autoloads devil-autoloads difftastic-autoloads
dired-filter-autoloads dired-sidebar-autoloads dired-subtree-autoloads
dired-hacks-utils-autoloads dirvish-autoloads doc-toc-autoloads
dockerfile-mode-autoloads dracula-theme-autoloads
earthfile-mode-autoloads eat-autoloads ediprolog-autoloads
eglot-booster-autoloads eglot-x-autoloads el-mock-autoloads
eldoc-box-autoloads elixir-ts-mode-autoloads
emacsql-sqlite-builtin-autoloads embark-consult-autoloads
consult-autoloads embark-autoloads eshell-vterm-autoloads esup-autoloads
eterm-256color-autoloads exec-path-from-shell-autoloads
expand-region-autoloads extmap-autoloads flycheck-clj-kondo-autoloads
flycheck-credo-autoloads flymake-credo-autoloads
flymake-flycheck-autoloads flycheck-autoloads free-keys-autoloads
fzf-autoloads general-autoloads ghub-autoloads git-link-autoloads
git-msg-prefix-autoloads git-ps1-mode-autoloads
github-browse-file-autoloads go-mode-autoloads graphql-mode-autoloads
graphviz-dot-mode-autoloads gruvbox-theme-autoloads autothemer-autoloads
heex-ts-mode-autoloads highlight-autoloads
highlight-indent-guides-autoloads highlight-indentation-autoloads
hl-column-autoloads hyperbole-autoloads kotl-autoloads hact set hhist
ialign-autoloads iedit-autoloads imenu-list-autoloads
impatient-mode-autoloads inf-elixir-autoloads inflections-autoloads
ivy-avy-autoloads avy-autoloads ivy-file-preview-autoloads
ivy-posframe-autoloads janet-mode-autoloads jsonnet-mode-autoloads
just-mode-autoloads kanagawa-theme-autoloads loccur-autoloads
lsp-ui-autoloads lsp-mode-autoloads eldoc-autoloads lua-mode-autoloads
magit-delta-autoloads marginalia-autoloads memoize-autoloads
minions-autoloads mise-autoloads inheritenv-autoloads
modus-themes-autoloads multiple-cursors-autoloads nano-theme-autoloads
nord-theme-autoloads nordic-night-theme-autoloads ob-async-autoloads
ob-prolog-autoloads ob-restclient-autoloads obsidian-autoloads
elgrep-autoloads markdown-mode-autoloads orderless-autoloads
org-appear-autoloads org-cliplink-autoloads org-clock-reminder-autoloads
org-modern-autoloads org-ql-autoloads org-re-reveal-autoloads
org-roam-ui-autoloads org-roam-autoloads emacsql-autoloads
org-super-agenda-autoloads org-tidy-autoloads org-transclusion-autoloads
outline-indent-autoloads ov-autoloads ox-clip-autoloads ox-gfm-autoloads
ox-report-autoloads org-msg-autoloads htmlize-autoloads
pabbrev-autoloads paredit-autoloads paren-face-autoloads
parseedn-autoloads parseclj-autoloads pdf-tools-autoloads
pfuture-autoloads pikchr-mode-autoloads pkl-mode-autoloads
plantuml-mode-autoloads deflate-autoloads platformio-mode-autoloads
async-autoloads polymode-autoloads popper-autoloads pos-tip-autoloads
posframe-autoloads prescient-autoloads projectile-autoloads
pueue-autoloads puni-autoloads easy-mmode quelpa-use-package-autoloads
quelpa-autoloads queue-autoloads quick-peek-autoloads
rainbow-delimiters-autoloads rainbow-mode-autoloads restclient-autoloads
rich-minority-autoloads rust-mode-autoloads scss-mode-autoloads
sed-mode-autoloads separedit-autoloads edit-indirect-autoloads
sesman-autoloads shades-of-purple-theme-autoloads shell-maker-autoloads
shrface-autoloads language-detection-autoloads org-autoloads
shrink-path-autoloads f-autoloads sideline-blame-autoloads
sideline-flymake-autoloads sideline-autoloads ht-autoloads
simple-httpd-autoloads smartparens-autoloads solo-jazz-theme-autoloads
souffle-mode-autoloads spacious-padding-autoloads spinner-autoloads
sqlformat-autoloads string-inflection-autoloads swiper-autoloads
ivy-autoloads tablist-autoloads tempel-autoloads textile-mode-autoloads
theme-anchor-autoloads tla-ts-mode-autoloads treepy-autoloads
treesit-auto-autoloads ts-autoloads s-autoloads dash-autoloads
typst-ts-mode-autoloads ultra-scroll-autoloads finder-inf
vc-jj-autoloads vc-msg-autoloads popup-autoloads vdiff-magit-autoloads
magit-autoloads pcase transient-autoloads magit-section-autoloads
llama-autoloads vdiff-autoloads hydra-autoloads lv-autoloads
verb-autoloads vertico-autoloads visual-fill-column-autoloads
visual-regexp-autoloads vterm-toggle-autoloads vterm-autoloads
w3m-autoloads web-mode-autoloads websocket-autoloads wgrep-ack-autoloads
wgrep-autoloads which-key-autoloads info with-editor-autoloads
xr-autoloads xterm-color-autoloads yaml-mode-autoloads
yaml-pro-autoloads yaml-autoloads yasnippet-capf-autoloads
yasnippet-autoloads zig-mode-autoloads reformatter-autoloads
zig-ts-mode-autoloads zmq-autoloads zones-autoloads zoutline-autoloads
package browse-url url url-proxy url-privacy url-expand url-methods
url-history url-cookie generate-lisp-file url-domsuf url-util mailcap
url-handlers url-parse auth-source cl-seq eieio eieio-core cl-macs icons
password-cache json subr-x map byte-opt gv bytecomp byte-compile
url-vars cl-loaddefs cl-lib rmc iso-transl tooltip cconv eldoc paren
electric uniquify ediff-hook vc-hooks lisp-float-type elisp-mode mwheel
term/ns-win ns-win ucs-normalize mule-util term/common-win tool-bar dnd
fontset image regexp-opt fringe tabulated-list replace newcomment
text-mode lisp-mode prog-mode register page tab-bar menu-bar rfn-eshadow
isearch easymenu timer select scroll-bar mouse jit-lock font-lock syntax
font-core term/tty-colors frame minibuffer nadvice seq simple cl-generic
indonesian philippine cham georgian utf-8-lang misc-lang vietnamese
tibetan thai tai-viet lao korean japanese eucjp-ms cp51932 hebrew greek
romanian slovak czech european ethiopic indian cyrillic chinese
composite emoji-zwj charscript charprop case-table epa-hook
jka-cmpr-hook help abbrev obarray oclosure cl-preloaded button loaddefs
theme-loaddefs faces cus-face macroexp files window text-properties
overlay sha1 md5 base64 format env code-pages mule custom widget keymap
hashtable-print-readable backquote threads kqueue cocoa ns lcms2
multi-tty make-network-process native-compile emacs)

Memory information:
((conses 16 1101389 955140) (symbols 48 63300 46)
 (strings 32 266045 75482) (string-bytes 1 8549146) (vectors 16 85385)
 (vector-slots 8 994988 103443) (floats 8 1028 413)
 (intervals 56 1820 379) (buffers 992 14))
[Message part 2 (text/html, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79023; Package emacs. (Tue, 15 Jul 2025 12:24:02 GMT) Full text and rfc822 format available.

Message #8 received at 79023 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Przemysław Alexander Kamiński
 <przemyslaw <at> kaminski.se>
Cc: 79023 <at> debbugs.gnu.org
Subject: Re: bug#79023: 30.1.90;
 Suspicion of memory leak on internal_redisplay (MacOS)
Date: Tue, 15 Jul 2025 15:23:13 +0300
> From: Przemysław Alexander Kamiński
>  <przemyslaw <at> kaminski.se>
> Date: Tue, 15 Jul 2025 09:12:47 +0200
> 
> it seems there's some memory leak happening in redisplay_internal
> function.
> 
> I've noticed that over time Emacs become slower and slower. After 2-3
> hours bug is noticable. Total - as reported by OS - usage is >2Gb. GC is
> working correctly and running it manually didn't change anything. Memory
> report marks only ~50mb, and total memory on relatively fresh instance
> is ~500mb. I've noticed that at approx 3Gb I start receiving "freezes of doom".

Given the above description, why did you decide the leak is in
redisplay_internal?

FWIW, I'm using Emacs 30.1.90 all the time, with sessions that last
several weeks, and its memory footprint, after leveling at several
hundred MB never grows more, certainly not at the rate you describe.
So either this is a macOS-specific problem, or something else is at
work here (perhaps one of the many packages you have activated?).

> Can't say anything more, if there's anything else I could try to
> debug/report let me know.

Well, for starters please explain why you think it's
redisplay_internal that leaks.  Also, if you can try older versions of
Emacs, please see if the same issue exists there.

And finally, what version of Emacs are you using and how did you build
it?  Is that Emacs 30.1.90 pretest built from the pretest tarball, or
is it something else?

Thanks.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79023; Package emacs. (Tue, 15 Jul 2025 13:03:02 GMT) Full text and rfc822 format available.

Message #11 received at 79023 <at> debbugs.gnu.org (full text, mbox):

From: Przemysław Alexander Kamiński
 <przemyslaw <at> kaminski.se>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 79023 <at> debbugs.gnu.org
Subject: Re: bug#79023: 30.1.90; Suspicion of memory leak on
 internal_redisplay (MacOS)
Date: Tue, 15 Jul 2025 15:01:55 +0200
[Message part 1 (text/plain, inline)]
On 15 Jul 2025, at 14:23, Eli Zaretskii wrote:

> Given the above description, why did you decide the leak is in
> redisplay_internal?

     39,652,925  72% - redisplay_internal (C function)
      1,797,080   3%  + eval
        279,056   0%  + jit-lock-function
         66,632   0%  + which-key--hide-popup-on-frame-size-change
         24,752   0%    mode-line-default-help-echo
         11,328   0%  + menu-bar-update-buffers

This is taken from just now. It seems like a lot of memory goes there. 
Given that I have 2Gbs of usage beyond ~40mb reporting I'd suspect 
something fishy is happening there.

And on paper everything looks fine - with single Elisp buffer Emacs 
reports: 57MiB as reserved for objects, ~30mb of Conses. There is 900Mb 
of total system usage which makes it top memory eater.

For context - I run HiDPI and refresh rate system though (4400x2400 with 
60hz - was 144hz before), which might explain why redisplay memory rise 
is happening quicker than for others.

>
> FWIW, I'm using Emacs 30.1.90 all the time, with sessions that last
> several weeks, and its memory footprint, after leveling at several
> hundred MB never grows more, certainly not at the rate you describe.
> So either this is a macOS-specific problem, or something else is at
> work here (perhaps one of the many packages you have activated?).

I'm quite sure that this is the problem with MacOS/NS implementation.

I've experienced similar behavior in raw and patched versions and rarely 
can hold a session for more than 2 days. Usually when Emacs went dead it 
went dead and that was it, I blamed it on setup, only today caught bloat 
when I was investigating performance deterioration. (and searching for 
it the general complain is "well Emacs on MacOS is slower than on 
Linux").

> Well, for starters please explain why you think it's
> redisplay_internal that leaks.  Also, if you can try older versions of
> Emacs, please see if the same issue exists there.

I'm quite positive it does, because I've observed this for at least 2 
years. Today it's much better than it was before, but still it bloats. I 
didn't think about running -Q, and that was simple enough to confirm 
that:

      1,561,924  54% + timer-event-handler
      1,185,948  41% - redisplay_internal (C function)
        287,011  10%  + jit-lock-function
         79,104   2%    file-remote-p
         13,312   0%  + kill-this-buffer-enabled-p
          8,184   0%    mode-line-default-help-echo

Usage is 230MiB of memory, reported 5MiB. leaks app (MacOS malloc leak 
tracer) reports barely 229kb of leaked memory and it reports 37MiB 
malloced out of 139MiB (usage dropped while I was writing this e-mail). 
Finally - redisplay_internal is the only place I saw memory going out 
(and just noticed that redisplay itself is good enough to start GC every 
couple seconds - 17GCs over 10s test period using -Q instance).

>
> And finally, what version of Emacs are you using and how did you build
> it?  Is that Emacs 30.1.90 pretest built from the pretest tarball, or
> is it something else?

MacOS built with emacs-plus - built through Homebrew from emacs-30 
branch right now, but I've seen this performance degredation over time 
on emacs-mac and emacs through MacPorts.

Best,
Przemysław Alexander Kamiński
[Message part 2 (text/html, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79023; Package emacs. (Tue, 15 Jul 2025 13:31:04 GMT) Full text and rfc822 format available.

Message #14 received at 79023 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Przemysław Alexander Kamiński
 <przemyslaw <at> kaminski.se>
Cc: 79023 <at> debbugs.gnu.org
Subject: Re: bug#79023: 30.1.90; Suspicion of memory leak on
 internal_redisplay (MacOS)
Date: Tue, 15 Jul 2025 16:30:23 +0300
> From: Przemysław Alexander Kamiński
>  <przemyslaw <at> kaminski.se>
> Cc: 79023 <at> debbugs.gnu.org
> Date: Tue, 15 Jul 2025 15:01:55 +0200
> 
> On 15 Jul 2025, at 14:23, Eli Zaretskii wrote:
> 
>  Given the above description, why did you decide the leak is in 
>  redisplay_internal?
> 
>  39,652,925  72% - redisplay_internal (C function)
>   1,797,080   3%  + eval
>     279,056   0%  + jit-lock-function
>      66,632   0%  + which-key--hide-popup-on-frame-size-change
>      24,752   0%    mode-line-default-help-echo
>      11,328   0%  + menu-bar-update-buffers
> 
> This is taken from just now. It seems like a lot of memory goes there. Given that I have 2Gbs of usage
> beyond ~40mb reporting I'd suspect something fishy is happening there.

This is not relevant.  The so-called "memory profiler" doesn't
profile memory usage, it just uses calls to memory-allocation
functions as an opportunity to profile Emacs.  So what your profile
says is that redisplay_internal was used a lot, but not that there's a
memory leak in it.

>  FWIW, I'm using Emacs 30.1.90 all the time, with sessions that last 
>  several weeks, and its memory footprint, after leveling at several 
>  hundred MB never grows more, certainly not at the rate you describe. 
>  So either this is a macOS-specific problem, or something else is at 
>  work here (perhaps one of the many packages you have activated?).
> 
> I'm quite sure that this is the problem with MacOS/NS implementation.

Then let's hear from other macOS users: does anyone else who uses
Emacs on macOS have similar experience wrt the Emacs memory footprint?

In any case, almost all of the code in redisplay_internal is not macOS
specific, so if there's a memory leak there, it is unlikely to affect
only the macOS build of Emacs.

>   1,561,924  54% + timer-event-handler
>   1,185,948  41% - redisplay_internal (C function)
>     287,011  10%  + jit-lock-function
>      79,104   2%    file-remote-p
>      13,312   0%  + kill-this-buffer-enabled-p
>       8,184   0%    mode-line-default-help-echo
> 
> Usage is 230MiB of memory, reported 5MiB. leaks app (MacOS malloc leak tracer) reports barely 229kb of
> leaked memory and it reports 37MiB malloced out of 139MiB (usage dropped while I was writing this e-mail).
> Finally - redisplay_internal is the only place I saw memory going out (and just noticed that redisplay itself is
> good enough to start GC every couple seconds - 17GCs over 10s test period using -Q instance).

See above: your interpretation of the "memory profile" is wrong.  In
particular, this profile cannot tell us whether we allocate more
memory than we free.

>  And finally, what version of Emacs are you using and how did you build 
>  it? Is that Emacs 30.1.90 pretest built from the pretest tarball, or 
>  is it something else?
> 
> MacOS built with emacs-plus - built through Homebrew from emacs-30 branch right now, but I've seen this
> performance degredation over time on emacs-mac and emacs through MacPorts.

Thanks.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79023; Package emacs. (Tue, 15 Jul 2025 13:53:02 GMT) Full text and rfc822 format available.

Message #17 received at 79023 <at> debbugs.gnu.org (full text, mbox):

From: Przemysław Alexander Kamiński
 <przemyslaw <at> kaminski.se>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 79023 <at> debbugs.gnu.org
Subject: Re: bug#79023: 30.1.90; Suspicion of memory leak on
 internal_redisplay (MacOS)
Date: Tue, 15 Jul 2025 15:52:20 +0200
On 15 Jul 2025, at 15:30, Eli Zaretskii wrote:

> See above: your interpretation of the "memory profile" is wrong.  In
> particular, this profile cannot tell us whether we allocate more
> memory than we free.
>

Well this memory profile is something that I would expect to be low and irrelevant. I don't have a proof, so marked as a suspicion.
I wouldn't be surprised if that'd be something that touched MacOS users only - I've seen plenty of complains about the performance and experienced it too, but AFAIK we're smaller crowd. Suspicion coms from the fact that I cannot see where the data is going and leaks tool is reporting low usage, so most likely this is outside of C realm.

I've done some extra testing, since I wouldn't be surprised if some release on a string was missing or something. On a fresh instance blinking cursor is enough to raise memory usage. 10mb over 4.5mb and garbage- didn't releaes memory.

I think I can reproduce test case and even think what might be the cause, as I looked around MacOS code for couple of minutes.

Best,
Przemysław Alexander Kamiński




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79023; Package emacs. (Wed, 16 Jul 2025 06:50:03 GMT) Full text and rfc822 format available.

Message #20 received at 79023 <at> debbugs.gnu.org (full text, mbox):

From: Przemysław Alexander Kamiński
 <przemyslaw <at> kaminski.se>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 79023 <at> debbugs.gnu.org
Subject: Re: bug#79023: 30.1.90; Suspicion of memory leak on
 internal_redisplay (MacOS)
Date: Wed, 16 Jul 2025 08:49:47 +0200
[Message part 1 (text/plain, inline)]
Yesterday I was able to hookup MacOS' Instruments.app to build Emacs. Took some effort to figure out, but once done it was rather easy. I'll make a short note and publish the steps.

Findings:
- There are multiple leaks, but most of them are very small in total they accrue ~1m per minute
- The total run was ~2.5m (it slows Emacs down so it's hard to use it all the time) and I cut off initialization leaks (~1.5m, some related to Toolbar initialization)
- I'm attaching two text files (not sure if it won't bounce)
  - First one are few example of complex loops - they seem to hit lisp_allign_malloc which seems to be related to MacOS-specific code
  - Second one are root loops.

I found few other weird things, e.g. it seems that opening a single midsize buffer processed approx. 2GiB of memory and that a single symbol allocates 1KiB of memory, but I don't think it's the proper thread to discuss further.

Of course there's more but sharing in text form is very difficult. In case someone wants to reproduce by themselves, what it takes is to add task/debug entitlements (see attached debug.plist) through signing. I had to remove com.apple.FinderInfo from emacs-plus build, not sure where it came from. Build was with debug symbols for easier debugging. Commands I used:

$ xattr -d com.apple.FinderInfo /path/to/Emacs.app
$ codesign -s - -v -f --entitlements /path/to/debug.plist /path/to/Emacs.app

After that I started Instruments.app set app bundle for analysis and launched from there.

Lot of interesting info, but slows down considerably when constantly probed. I'm somewhat stoked about this because I'm optimization freak and Emacs speed on MacOS wasn't something great - it usually deteriorates after hours - I blamed fancy packages like Marginalia, but if it leaks drops on small allocations it would make sense why it accelerated the process.

Best,
Przemysław Alexander Kamiński
[leaks2.txt (text/plain, attachment)]
[leaks1.txt (text/plain, attachment)]
[debug.plist (text/plain, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79023; Package emacs. (Wed, 16 Jul 2025 11:10:02 GMT) Full text and rfc822 format available.

Message #23 received at 79023 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Przemysław Alexander Kamiński
 <przemyslaw <at> kaminski.se>
Cc: 79023 <at> debbugs.gnu.org
Subject: Re: bug#79023: 30.1.90; Suspicion of memory leak on
 internal_redisplay (MacOS)
Date: Wed, 16 Jul 2025 14:08:13 +0300
> From: Przemysław Alexander Kamiński
>  <przemyslaw <at> kaminski.se>
> Cc: 79023 <at> debbugs.gnu.org
> Date: Tue, 15 Jul 2025 15:52:20 +0200
> 
> I've done some extra testing, since I wouldn't be surprised if some release on a string was missing or something. On a fresh instance blinking cursor is enough to raise memory usage. 10mb over 4.5mb and garbage- didn't releaes memory.

Please describe this recipe in more detail, starting from "emacs -Q",
so others could try repeating it.  Also, please describe how you
measure the memory leaks and what are the numbers you see.

> I think I can reproduce test case and even think what might be the cause, as I looked around MacOS code for couple of minutes.

Please do, and thanks.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79023; Package emacs. (Wed, 16 Jul 2025 12:04:02 GMT) Full text and rfc822 format available.

Message #26 received at 79023 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Przemysław Alexander Kamiński
 <przemyslaw <at> kaminski.se>
Cc: 79023 <at> debbugs.gnu.org
Subject: Re: bug#79023: 30.1.90; Suspicion of memory leak on
 internal_redisplay (MacOS)
Date: Wed, 16 Jul 2025 15:02:40 +0300
> From: Przemysław Alexander Kamiński
>  <przemyslaw <at> kaminski.se>
> Cc: 79023 <at> debbugs.gnu.org
> Date: Wed, 16 Jul 2025 08:49:47 +0200
> 
> Yesterday I was able to hookup MacOS' Instruments.app to build Emacs. Took some effort to figure out, but once done it was rather easy. I'll make a short note and publish the steps.
> 
> Findings:
> - There are multiple leaks, but most of them are very small in total they accrue ~1m per minute
> - The total run was ~2.5m (it slows Emacs down so it's hard to use it all the time) and I cut off initialization leaks (~1.5m, some related to Toolbar initialization)
> - I'm attaching two text files (not sure if it won't bounce)
>   - First one are few example of complex loops - they seem to hit lisp_allign_malloc which seems to be related to MacOS-specific code
>   - Second one are root loops.
> 
> I found few other weird things, e.g. it seems that opening a single midsize buffer processed approx. 2GiB of memory and that a single symbol allocates 1KiB of memory, but I don't think it's the proper thread to discuss further.
> 
> Of course there's more but sharing in text form is very difficult. In case someone wants to reproduce by themselves, what it takes is to add task/debug entitlements (see attached debug.plist) through signing. I had to remove com.apple.FinderInfo from emacs-plus build, not sure where it came from. Build was with debug symbols for easier debugging. Commands I used:
> 
> $ xattr -d com.apple.FinderInfo /path/to/Emacs.app
> $ codesign -s - -v -f --entitlements /path/to/debug.plist /path/to/Emacs.app
> 
> After that I started Instruments.app set app bundle for analysis and launched from there.
> 
> Lot of interesting info, but slows down considerably when constantly probed. I'm somewhat stoked about this because I'm optimization freak and Emacs speed on MacOS wasn't something great - it usually deteriorates after hours - I blamed fancy packages like Marginalia, but if it leaks drops on small allocations it would make sense why it accelerated the process.

Thanks, but I don't yet understand how to use the information you
posted for trying to find the alleged memory leaks.  Some questions
below.

I also am not sure these are real leaks.  Emacs Lisp programs trigger
memory allocation when they create Lisp objects, but they don't
themselves free memory they allocated this way when the objects are no
longer needed.  Instead, the process known as "garbage collection"
(GC) is initiated by Emacs from time to time, and "collects garbage"
by finding Lisp objects no longer referenced by any other object, and
freeing their memory.  (Apologies for the lecture if you already know
all that.)  Thus, programs that expect memory to be released
immediately when the object goes out of scope will think Emacs is a
very leaky application, because that's not how Emacs Lisp works.

Are you sure the information you collected is not of this kind?

> Root leaks
> 
> _malloc_zone_malloc_instrumented_or_legacy
> lmalloc
> make_blv
> Fmake_local_variable
> F636f6d70696c6174696f6e2d6d6f6465_compilation_mode_0
> Ffuncall
> F656d6163732d6c6973702d636f6d70696c6174696f6e2d6d6f6465_emacs_lisp_compilation_mode_0
> Ffuncall
> F636f6d702d2d72756e2d6173796e632d776f726b657273_comp__run_async_workers_0
> Ffuncall
> F6e61746976652d2d636f6d70696c652d6173796e63_native__compile_async_0
> Ffuncall
> F6e61746976652d636f6d70696c652d6173796e63_native_compile_async_0
> eval_sub
> Fprogn
> funcall_lambda
> Ffuncall
> Ffuncall
> F74696d65722d6576656e742d68616e646c6572_timer_event_handler_0
> Ffuncall
> timer_check_2
> main
> start

What are "root leaks", and how to interpret the above sequence of
function names?

> 1	 Malloc 544,00 KiB - 1 nodes	Complex Cycle
> _malloc_zone_memalign
> lisp_align_malloc
> Fcons
> Fcopy_sequence
> timer_check
> readable_events
> get_input_pending
> main
> start

What does the above attempt to tell?

Thanks.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79023; Package emacs. (Wed, 16 Jul 2025 12:37:02 GMT) Full text and rfc822 format available.

Message #29 received at 79023 <at> debbugs.gnu.org (full text, mbox):

From: Przemysław Alexander Kamiński
 <przemyslaw <at> kaminski.se>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 79023 <at> debbugs.gnu.org
Subject: Re: bug#79023: 30.1.90; Suspicion of memory leak on
 internal_redisplay (MacOS)
Date: Wed, 16 Jul 2025 14:35:51 +0200
> I also am not sure these are real leaks.  Emacs Lisp programs trigger
> memory allocation when they create Lisp objects, but they don't
> themselves free memory they allocated this way when the objects are no
> longer needed.  Instead, the process known as "garbage collection"
> (GC) is initiated by Emacs from time to time, and "collects garbage"
> by finding Lisp objects no longer referenced by any other object, and
> freeing their memory.  (Apologies for the lecture if you already know
> all that.)  Thus, programs that expect memory to be released
> immediately when the object goes out of scope will think Emacs is a
> very leaky application, because that's not how Emacs Lisp works.
>
> Are you sure the information you collected is not of this kind?

I'm quite confident it's not the case. Garbage collector doesn't clean it up.

Here's my line of thinking:
- 1Gb of Emacs after launch and list-packages is huge (even with hefty config)
- This wouldn't go unnoticed, so most likely isn't the problem of the core code...
- I searched before and found also other entries on web which point to Emacs performance on MacOS
- Also I have Emacs config synced to my gaming Windows machine and I didn't experience any slowness (it was blazingly fast actually)
- All profiling I've done so far look good
- Which means something must be happening on MacOS integration

The facts for me are:
- Emacs is bloating over time and freezes at some point for unknown reasons
- Over the time Emacs is more and more slugish, M-x taking 0.7s to think etc.
- After multiple scrupoulous review of config, timers background processess etc.

I've noticed that on built Emacs there's allocation for every single blink of cursor on screen. Isn't this weird even if that wouldn't leak.

I've done more testing today with different build flags and some guesses that I have:
- Some allocated strings aren't marked as autorelease, so they stay
- For some reason system doesn't know that this allocated space is no longer used and doesn't GC it
- Slowness is caused by immense fragmentation of memory caused by small allocations far away from each other
- During deallocation hashes aren't deallocated completely
- There's missing some MacOS specific call that should be made in order for it to optimize
- NSEvents are being stopped in flight without deallocation and they keep references to the memory

However, after working in recent months with Zig and C I've been able to get instrumentation running on MacOS and I'd like to fix it.

Best,
Przemysław Alexander Kamiński




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79023; Package emacs. (Wed, 16 Jul 2025 12:55:02 GMT) Full text and rfc822 format available.

Message #32 received at 79023 <at> debbugs.gnu.org (full text, mbox):

From: Przemysław Alexander Kamiński
 <przemyslaw <at> kaminski.se>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 79023 <at> debbugs.gnu.org
Subject: Re: bug#79023: 30.1.90; Suspicion of memory leak on
 internal_redisplay (MacOS)
Date: Wed, 16 Jul 2025 14:54:06 +0200
[Message part 1 (text/plain, inline)]

On 16 Jul 2025, at 13:08, Eli Zaretskii wrote:

>> From: Przemysław Alexander Kamiński
>>  <przemyslaw <at> kaminski.se>
>> Cc: 79023 <at> debbugs.gnu.org
>> Date: Tue, 15 Jul 2025 15:52:20 +0200
>>
>> I've done some extra testing, since I wouldn't be surprised if some 
>> release on a string was missing or something. On a fresh instance 
>> blinking cursor is enough to raise memory usage. 10mb over 4.5mb and 
>> garbage- didn't releaes memory.
>
> Please describe this recipe in more detail, starting from "emacs -Q",
> so others could try repeating it.  Also, please describe how you
> measure the memory leaks and what are the numbers you see.
>

Unfortunatelly there's nothing more I can do, Instruments is strictly 
GUI app. All text has to be extracted manually. I know it's probably the 
worst way to do, but I recorded example session with `emacs -Q`.

https://www.youtube.com/watch?v=_korzyoMXfY

It'd be nice if someone smarter than me and more experienced in MacOS 
system programming took a look on this, my current line is to have a 
build pipeline and throw different ideas until I can find something that 
works.

>> I think I can reproduce test case and even think what might be the 
>> cause, as I looked around MacOS code for couple of minutes.
>
> Please do, and thanks.

I've been able to reproduce by using blinking cursor (setq 
blink-cursor-blinks 0 blink-cursor-interval 0.1).
Attached patch seemed to decrease number of allocations and leaks but 
it's not enough to make a dent.

Best,
Przemysław Alexander Kamiński
[Message part 2 (text/html, inline)]
[memleak.patch (text/plain, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79023; Package emacs. (Wed, 16 Jul 2025 13:26:01 GMT) Full text and rfc822 format available.

Message #35 received at 79023 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Przemysław Alexander Kamiński
 <przemyslaw <at> kaminski.se>, Alan Third <alan <at> idiocy.org>
Cc: 79023 <at> debbugs.gnu.org
Subject: Re: bug#79023: 30.1.90; Suspicion of memory leak on
 internal_redisplay (MacOS)
Date: Wed, 16 Jul 2025 16:24:41 +0300
> From: Przemysław Alexander Kamiński
>  <przemyslaw <at> kaminski.se>
> Cc: 79023 <at> debbugs.gnu.org
> Date: Wed, 16 Jul 2025 14:35:51 +0200
> 
> > I also am not sure these are real leaks.  Emacs Lisp programs trigger
> > memory allocation when they create Lisp objects, but they don't
> > themselves free memory they allocated this way when the objects are no
> > longer needed.  Instead, the process known as "garbage collection"
> > (GC) is initiated by Emacs from time to time, and "collects garbage"
> > by finding Lisp objects no longer referenced by any other object, and
> > freeing their memory.  (Apologies for the lecture if you already know
> > all that.)  Thus, programs that expect memory to be released
> > immediately when the object goes out of scope will think Emacs is a
> > very leaky application, because that's not how Emacs Lisp works.
> >
> > Are you sure the information you collected is not of this kind?
> 
> I'm quite confident it's not the case. Garbage collector doesn't clean it up.

How do you see that GC doesn't clean up?

> Here's my line of thinking:
> - 1Gb of Emacs after launch and list-packages is huge (even with hefty config)

Sorry, I don't understand what that means.  Are you saying that you
load many packages at startup?  How many?

Could we please start the measurements from "emacs -Q", to avoid
potential influence of too many unknowns?

I've just left "emacs -Q" running for 10 minutes, after setting
blink-cursor-blinks to zero (so it keeps blinking indefinitely), and
not only did it not grow in memory, it _freed_ some memory.

> - This wouldn't go unnoticed, so most likely isn't the problem of the core code...
> - I searched before and found also other entries on web which point to Emacs performance on MacOS
> - Also I have Emacs config synced to my gaming Windows machine and I didn't experience any slowness (it was blazingly fast actually)
> - All profiling I've done so far look good
> - Which means something must be happening on MacOS integration

It's possible that on macOS there's some leak, but we need a much more
specific information to find where it happens.  Just looking at the
memory allocation calls will never tell us anything useful, because
Emacs calls malloc _a_lot_.

> The facts for me are:
> - Emacs is bloating over time and freezes at some point for unknown reasons
> - Over the time Emacs is more and more slugish, M-x taking 0.7s to think etc.
> - After multiple scrupoulous review of config, timers background processess etc.

I'm not arguing against the facts.

> I've noticed that on built Emacs there's allocation for every single blink of cursor on screen. Isn't this weird even if that wouldn't leak.

No, it isn't weird at all.  Cursor-blinking in Emacs is not a terminal
function, it is Emacs actively turning the cursor off and on again,
every 0.5 sec.  To do that, it runs a 2 Hz timer, which expires every
0.5 sec, then turns the cursor on or off, and then computes the time
it should expire next.  All these actions allocate memory (which is
then freed, some of it immediately and some later, via GC).

> I've done more testing today with different build flags and some guesses that I have:
> - Some allocated strings aren't marked as autorelease, so they stay

What do you mean by "marked autorelease"?  Lisp strings are released
by GC when they are no longer referenced from any other object.
There's no such thing as "autorelease strings" in Emacs.

> - For some reason system doesn't know that this allocated space is no longer used and doesn't GC it

How do you see that?  And which space is it, allocated by what
functions?

> - Slowness is caused by immense fragmentation of memory caused by small allocations far away from each other

Emacs relies on the system malloc to be able to avoid fragmentation.
Where that is not guaranteed (such as on MS-Windows), Emacs has its
own replacements for the system malloc, which avoid fragmentation.

> - During deallocation hashes aren't deallocated completely

Which hashes are those?

> - There's missing some MacOS specific call that should be made in order for it to optimize

Which calls, and where are they missing?

> - NSEvents are being stopped in flight without deallocation and they keep references to the memory

This should be addressed by some macOS expert.  Alan, can you help
here?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79023; Package emacs. (Wed, 16 Jul 2025 14:17:02 GMT) Full text and rfc822 format available.

Message #38 received at 79023 <at> debbugs.gnu.org (full text, mbox):

From: Przemysław Alexander Kamiński
 <przemyslaw <at> kaminski.se>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: Alan Third <alan <at> idiocy.org>, 79023 <at> debbugs.gnu.org
Subject: Re: bug#79023: 30.1.90; Suspicion of memory leak on
 internal_redisplay (MacOS)
Date: Wed, 16 Jul 2025 16:15:54 +0200
> Sorry, I don't understand what that means.  Are you saying that you
> load many packages at startup?  How many?
>
> Could we please start the measurements from "emacs -Q", to avoid
> potential influence of too many unknowns?

Probably around 100-200, and it's mostly popular setup: LSP/Vertico+friends some theme and fonts.
This shouldn't be 1Gb at start right?

>
> I've just left "emacs -Q" running for 10 minutes, after setting
> blink-cursor-blinks to zero (so it keeps blinking indefinitely), and
> not only did it not grow in memory, it _freed_ some memory.

Are you on MacOS? Because that patch that I made fixed the issue for me as well (the one with autorelease).
If you are than it would mean that issue might be deeper and be caused by gcc installation... that'd be fun..

> It's possible that on macOS there's some leak, but we need a much more
> specific information to find where it happens.  Just looking at the
> memory allocation calls will never tell us anything useful, because
> Emacs calls malloc _a_lot_.

I know, trying to make it happen. IMO "emacs -Q" won't help because if leak happens on local object allocation or event handling there won't be outliers.
I can confirm at least one thing though - if window isn't drawn, Instruments doesn't report any leaks.

>> I've noticed that on built Emacs there's allocation for every single blink of cursor on screen. Isn't this weird even if that wouldn't leak.
>
> No, it isn't weird at all.  (...) All these actions allocate memory (which is
> then freed, some of it immediately and some later, via GC).
>
I'm spoiled by my recent work with Zig because and would expect that there's pool or arena, I'll look into this when I can shuffle the code instead of rebuilding it from scratch.

>> I've done more testing today with different build flags and some guesses that I have:
>> - Some allocated strings aren't marked as autorelease, so they stay
>
> What do you mean by "marked autorelease"?  Lisp strings are released
> by GC when they are no longer referenced from any other object.
> There's no such thing as "autorelease strings" in Emacs.

Not in Emacs, but it's in Cocoa. As far as I know it's using ARC. Some NSStrings are allocated in integration module.
Since this allocation is outside of normal malloc I wouldn't expect it to be GC by Emacs (still on my theory that the bug sits in integration code).

I'm not a Objective-C developer, but some NSStrings are marked with "autorelease" upon creation and some are not - I'm suspicious.
Could it be the cause if that'd be single glyph that can't be released...

>> - For some reason system doesn't know that this allocated space is no longer used and doesn't GC it
> How do you see that?  And which space is it, allocated by what
> functions?

After 4 hours of usage I have 2Gb of memory kept. Garbage collection doesn't touch it at all.
I don't know what exactly because unfortunatelly I didn't run Emacs long enough for it to gather data.

>> - Slowness is caused by immense fragmentation of memory caused by small allocations far away from each other
>
> Emacs relies on the system malloc to be able to avoid fragmentation.
> Where that is not guaranteed (such as on MS-Windows), Emacs has its
> own replacements for the system malloc, which avoid fragmentation.

I'm wondering if the build system that _most_ MacOS builds are using aren't at fault and use gcc's one.
It would make sense - on Windows Emacs feels snappier than on MacOS..

>> - During deallocation hashes aren't deallocated completely
> Which hashes are those?

I was looking at

hash_table_alloc_bytes (ptrdiff_t nbytes) ATTRIBUTE_MALLOC_SIZE ((1));
hash_table_free_bytes (void *p, ptrdiff_t nbytes);

There seems to be some calculation during release, maybe something goes wrong?

>> - There's missing some MacOS specific call that should be made in order for it to optimize
> Which calls, and where are they missing?

Probably Alan (hi!) could help; I have no idea. But I know what happens when you don't type "sync<RET>" before you pull out the floppy ;-)

Best,
Przemysław Alexander Kamiński




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79023; Package emacs. (Wed, 16 Jul 2025 14:46:02 GMT) Full text and rfc822 format available.

Message #41 received at 79023 <at> debbugs.gnu.org (full text, mbox):

From: Alan Third <alan <at> idiocy.org>
To: Przemysław Alexander Kamiński
 <przemyslaw <at> kaminski.se>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 79023 <at> debbugs.gnu.org
Subject: Re: bug#79023: 30.1.90; Suspicion of memory leak on
 internal_redisplay (MacOS)
Date: Wed, 16 Jul 2025 15:45:21 +0100
On Wed, Jul 16, 2025 at 02:54:06PM +0200, Przemysław Alexander Kamiński wrote:
> 
> diff --git a/src/nsfont.m b/src/nsfont.m
> index b8aa6764..f99980b1 100644
> --- a/src/nsfont.m
> +++ b/src/nsfont.m
> @@ -529,6 +529,10 @@ static void ns_glyph_metrics (struct nsfont_info *font_info,
>        chars[95] = '\0';
>  
>        ascii_printable = [[NSString alloc] initWithFormat: @"%s", chars];
> +      if (ascii_printable != nil )
> +      {
> +        [ascii_printable autorelease];
> +      }
>      }
>  
>    if (w < (CGFloat) 0.0)

Is this the full patch? Unfortunately nsfont.m isn't used on macos,
it's only for GNUstep.

Also I'm pretty sure that when using alloc the object's lifetime is
restricted to the calling function, you need to retain the object if
you want to keep it.

I'm not saying we definitely don't make a mistake somewhere with
retain/release, but this probably isn't it.
-- 
Alan Third




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79023; Package emacs. (Wed, 16 Jul 2025 14:52:02 GMT) Full text and rfc822 format available.

Message #44 received at 79023 <at> debbugs.gnu.org (full text, mbox):

From: Przemysław Alexander Kamiński
 <przemyslaw <at> kaminski.se>
To: Alan Third <alan <at> idiocy.org>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 79023 <at> debbugs.gnu.org
Subject: Re: bug#79023: 30.1.90; Suspicion of memory leak on
 internal_redisplay (MacOS)
Date: Wed, 16 Jul 2025 16:51:24 +0200
> Is this the full patch? Unfortunately nsfont.m isn't used on macos,
> it's only for GNUstep.

Yup :)

> Also I'm pretty sure that when using alloc the object's lifetime is
> restricted to the calling function, you need to retain the object if
> you want to keep it.

It's marked as a static pointer, so I believe it wouldn't be cleared.
Yet i'm completely out of my water here.

> I'm not saying we definitely don't make a mistake somewhere with
> retain/release, but this probably isn't it.

Even if it was then it wasn't impactful anyway, so I wouldn't focus on that
at all.

Best,
Przemysław Alexander Kamiński




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79023; Package emacs. (Wed, 16 Jul 2025 16:46:02 GMT) Full text and rfc822 format available.

Message #47 received at 79023 <at> debbugs.gnu.org (full text, mbox):

From: Przemysław Alexander Kamiński
 <przemyslaw <at> kaminski.se>
To: Alan Third <alan <at> idiocy.org>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 79023 <at> debbugs.gnu.org
Subject: Re: bug#79023: 30.1.90; Suspicion of memory leak on
 internal_redisplay (MacOS)
Date: Wed, 16 Jul 2025 18:45:47 +0200
[Message part 1 (text/plain, inline)]
Update to the topic:

- I've setup up debug pipeline and was able to make a proper clean build 
and ensured GC plenty had plenty time to grab (snapshots every 30s)
- Only minor leaks are remaining
- I started looking at the allocations: on clean instance moving 
mouse/resizing window was expensive (see excerpt)
- Instance with uptime of 1 hour it has footprint of 405MiB (mind the 
debugging symbols though)

Best,
Przemysław Alexander Kamiński

---


20.06 MB      99.0%	6421	 	start
20.06 MB      99.0%	6421	 	 main
20.06 MB      99.0%	6421	 	  Frecursive_edit
20.06 MB      99.0%	6421	 	   recursive_edit_1
20.06 MB      99.0%	6421	 	    command_loop
20.06 MB      99.0%	6421	 	     command_loop.cold.1
20.06 MB      99.0%	6421	 	      internal_catch
20.06 MB      99.0%	6421	 	       command_loop_2
20.06 MB      99.0%	6421	 	        internal_condition_case
20.06 MB      99.0%	6421	 	         command_loop_1
20.04 MB      98.9%	6274	 	          read_key_sequence
20.04 MB      98.9%	6273	 	           read_char
19.24 MB      94.9%	588	 	            read_decoded_event_from_main_queue
19.24 MB      94.9%	588	 	             read_event_from_main_queue
19.24 MB      94.9%	587	 	              kbd_buffer_get_event
19.24 MB      94.9%	587	 	               wait_reading_process_output
11.11 MB      54.8%	584	 	                ns_select_1
11.11 MB      54.8%	584	 	                 -[EmacsApp run]
11.11 MB      54.8%	584	 	                  -[NSApplication run]
11.09 MB      54.7%	558	 	                   -[NSApplication 
_handleEvent:]
11.09 MB      54.7%	558	 	                    -[EmacsApp sendEvent:]
11.09 MB      54.7%	558	 	                     
-[NSApplication(NSEventRouting) sendEvent:]
11.09 MB      54.7%	558	 	                      
-[NSWindow(NSEventRouting) sendEvent:]
11.09 MB      54.7%	558	 	                       
-[NSWindow(NSEventRouting) _reallySendEvent:isDelayedEvent:]
11.09 MB      54.7%	558	 	                        
-[NSWindow(NSEventRouting) _handleMouseDownEvent:isDelayedEvent:]
11.09 MB      54.7%	558	 	                         -[NSThemeFrame 
mouseDown:]
11.09 MB      54.7%	558	 	                          -[NSThemeFrame 
handleMouseDown:]
11.09 MB      54.7%	558	 	                           -[NSTitledFrame 
attemptResizeWithEvent:]
11.09 MB      54.7%	558	 	                            
-[NSWindow(NSWindowResizing) _resizeWithEvent:]
11.07 MB      54.6%	416	 	                             
-[NSApplication(NSEventRouting) 
_nextEventMatchingEventMask:untilDate:inMode:dequeue:]
7.66 KB       0.0%	88	 	                             
-[NSWindow(NSWindowResizing) 
_frame:resizedFromEdge:withDelta:withEvent:withState:]
7.34 KB       0.0%	29	 	                             -[EmacsWindow 
setFrame:display:]
3.27 KB       0.0%	21	 	                             -[NSWindow 
_endLiveResize]
384 Bytes    0.0%	2	 	                             -[NSAutoreleasePool 
drain]
96 Bytes    0.0%	1	 	                             
-[NSWindow(NSScreenLayout) _saveWindowLayoutForScreenLayout]
64 Bytes    0.0%	1	 	                             _objc_msgSend_uncached
19.36 KB       0.0%	26	 	                   
-[NSApplication(NSEventRouting) 
_nextEventMatchingEventMask:untilDate:inMode:dequeue:]
8.13 MB      40.0%	3	 	                detect_input_pending_run_timers
8.13 MB      40.0%	3	 	                 flush_frame
8.13 MB      40.0%	3	 	                  ns_flush_display
8.13 MB      40.0%	3	 	                   ns_read_socket_1
8.13 MB      40.0%	3	 	                    -[EmacsApp run]
8.13 MB      40.0%	3	 	                     -[NSApplication run]
8.13 MB      40.0%	3	 	                      -[NSApplication 
_handleEvent:]
8.13 MB      40.0%	3	 	                       -[EmacsApp sendEvent:]
8.13 MB      40.0%	3	 	                        
-[NSApplication(NSEventRouting) sendEvent:]
8.13 MB      40.0%	3	 	                         routeMouseMovedEvent
8.13 MB      40.0%	3	 	                          
-[NSWindow(NSEventRouting) sendEvent:]
8.13 MB      40.0%	3	 	                           
-[NSWindow(NSEventRouting) _reallySendEvent:isDelayedEvent:]
8.13 MB      40.0%	3	 	                            _routeMouseMovedEvent
8.13 MB      40.0%	3	 	                             -[EmacsView 
mouseMoved:]
8.13 MB      40.0%	3	 	                              
ns_note_mouse_movement
8.13 MB      40.0%	3	 	                               -[EmacsView 
lockFocus]
8.13 MB      40.0%	3	 	                                -[EmacsLayer 
getContext]
8.13 MB      40.0%	3	 	                                 IOSurfaceCreate
8.13 MB      40.0%	2	 	                                  -[IOSurface 
initWithProperties:]
8.13 MB      40.0%	2	 	                                   
IOSurfaceClientCreateChild
400 Bytes    0.0%	1	 	                                    
_ioSurfaceClientCreateWithLockResult
400 Bytes    0.0%	1	 	                                     
_malloc_type_malloc_outlined
16 Bytes    0.0%	1	 	                                  
_objc_rootAllocWithZone
16 Bytes    0.0%	1	 	                                   
_malloc_type_calloc_outlined
[Message part 2 (text/html, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79023; Package emacs. (Thu, 17 Jul 2025 13:36:04 GMT) Full text and rfc822 format available.

Message #50 received at 79023 <at> debbugs.gnu.org (full text, mbox):

From: Przemysław Alexander Kamiński
 <przemyslaw <at> kaminski.se>
To: Alan Third <alan <at> idiocy.org>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 79023 <at> debbugs.gnu.org
Subject: Re: bug#79023: 30.1.90; Suspicion of memory leak on
 internal_redisplay (MacOS)
Date: Thu, 17 Jul 2025 15:34:51 +0200
[Message part 1 (text/plain, inline)]
I'm confident I've been able to found the root cause, no fix yet.

It's easy to reproduce: start new instance, grab resize handle and 
resize away.

I'm looking right now at a trace 23.3 seconds long trace. It has:
- "redisplay" 644 420 times allocating (but not leaking)
- total transient allocation vokume is 1.6 GB
- when removing windowWillResize/setFrame/layoutSublayersOfLayer there 
are only 1765 extra allocations

I think that overall slowness comes from that and fragmentation that 
comes with it. After some time I can imagine it's difficult to grab a 
2KiB slot from OS.

The outliers seems to be drawing glyphs, but I wouldn't focus on it 
first.

IMO there are two root causes:
- Major one: processing all the events without filtering (I have 5397 
attemptResizeWithEvent events handled in 10 seconds - I'm sure I didn't 
resize windows for that long)
- Minor one:  inefficient redrawing, but given number of allocations I 
think that autorelease pool might handle it (once it stops processing 
100MiB/second event streams ;-))

I'll try do deliver some prototype, but I'm not sure if that'd be 
anything integration-worthy.

Best,
Przemysław Alexander Kamiński

---

Most allocation-heavy stacktrace tail (count is total allocations in the 
inspected, 10s long frame):

2	172166  ns_draw_glyph_string_foreground 
[inlined]	emacs	emacs/src/nsterm.m:4278	
1	172166  macfont_draw	emacs	emacs/src/macfont.m:2951	


Transient allocations trace excerpt:

1878.09 MB     100.0%	1613815	 	emacs	-[EmacsApp run]
1874.40 MB      99.8%	1576278	 	emacs	 -[EmacsApp sendEvent:]
1653.78 MB      88.0%	644420	 	emacs	  -[EmacsView 
layoutSublayersOfLayer:]
  24.48 MB       1.3%	184083	 	emacs	  -[EmacsWindow setFrame:display:]
  44.38 MB       2.3%	143554	 	emacs	  -[EmacsView 
windowWillResize:toSize:]
 200.22 KB       0.0%	2237	 	emacs	  -[EmacsView mouseMoved:]
  17.88 KB       0.0%	520	 	emacs	  -[EmacsWindow 
constrainFrameRect:toScreen:]
   7.72 KB       0.0%	494	 	emacs	  -[EmacsLayer display]
  25.00 KB       0.0%	480	 	emacs	  -[EmacsApp stop:]
  77.17 KB       0.0%	177	 	emacs	  -[EmacsView viewDidEndLiveResize]
  14.62 KB       0.0%	78	 	emacs	  ns_send_appdefined
  20.58 KB       0.0%	68	 	emacs	  -[EmacsView windowDidResignKey:]
  14.09 KB       0.0%	213	 	emacs	 -[EmacsLayer display]
   5.73 KB       0.0%	65	 	emacs	 -[EmacsWindow 
accessibilityAttributeValue:]
    192 Bytes    0.0%	1	 	emacs	 ns_send_appdefined
[Message part 2 (text/html, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79023; Package emacs. (Thu, 17 Jul 2025 14:38:02 GMT) Full text and rfc822 format available.

Message #53 received at 79023 <at> debbugs.gnu.org (full text, mbox):

From: Alan Third <alan <at> idiocy.org>
To: Przemysław Alexander Kamiński
 <przemyslaw <at> kaminski.se>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 79023 <at> debbugs.gnu.org
Subject: Re: bug#79023: 30.1.90; Suspicion of memory leak on
 internal_redisplay (MacOS)
Date: Thu, 17 Jul 2025 15:37:21 +0100
On Thu, Jul 17, 2025 at 03:34:51PM +0200, Przemysław Alexander Kamiński wrote:
> I'm confident I've been able to found the root cause, no fix yet.
> 
> It's easy to reproduce: start new instance, grab resize handle and resize
> away.

It could be worth looking into whether we're releasing IOSurface's
correctly. I've had a look and the code looks OK to me, but I'm not an
expert on their use.

Basically, every time the system decides to display a new window size
it will release all the IOSurfaces and generate at least one new one
at the new size.

We then call redisplay to fill in that new buffer.

Obviously in the midst of a resize that's going to result in quite a
lot of work, and the IOSurface buffers can be quite big, which is why
I thought of them first.

-- 
Alan Third




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79023; Package emacs. (Thu, 17 Jul 2025 15:03:01 GMT) Full text and rfc822 format available.

Message #56 received at 79023 <at> debbugs.gnu.org (full text, mbox):

From: Przemysław Alexander Kamiński
 <przemyslaw <at> kaminski.se>
To: Alan Third <alan <at> idiocy.org>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 79023 <at> debbugs.gnu.org
Subject: Re: bug#79023: 30.1.90; Suspicion of memory leak on
 internal_redisplay (MacOS)
Date: Thu, 17 Jul 2025 17:02:11 +0200
[Message part 1 (text/plain, inline)]
On 17 Jul 2025, at 16:37, Alan Third wrote:

> On Thu, Jul 17, 2025 at 03:34:51PM +0200, Przemysław Alexander 
> Kamiński wrote:
> It could be worth looking into whether we're releasing IOSurface's
> correctly. I've had a look and the code looks OK to me, but I'm not an
> expert on their use.

It's definitelly fine. Objects are released and are hefty but there are 
only few allocations.

I done the stupidest fix possible. I put 0.1 sleep in 
layoutSublayersOfLayer and then 0.05 sleep for windowWillResize.

Resizing is not so smooth but:
- Number of allocations dropped considerably
- Instance, after furious resizing, sits at 263MiB instead of 1.6GiB

I saw some allocations still going, so investigated and... tracing 
process.
It looks like with slowed down redrawing it can reuse object pool 
without expanding it and keeping overal memory low.

I ran this instance with my config and it properly shrinks memory usage 
while sitting at 500MiB of stable usage. On top of it - memory usage 
seems to get back to baseline after further resizing. I'm going to build 
it with all the libs/flags I use usually and run it for some time to see 
if there aren't any issues with it.

Best,
Przemysław Alexander Kamiński

[Message part 2 (text/html, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79023; Package emacs. (Mon, 21 Jul 2025 19:17:02 GMT) Full text and rfc822 format available.

Message #59 received at 79023 <at> debbugs.gnu.org (full text, mbox):

From: Rudolf Adamkovič <rudolf <at> adamkovic.org>
To: Eli Zaretskii <eliz <at> gnu.org>, Przemysław Alexander
 Kamiński <przemyslaw <at> kaminski.se>
Cc: 79023 <at> debbugs.gnu.org
Subject: Re: bug#79023: 30.1.90; Suspicion of memory leak on
 internal_redisplay (MacOS)
Date: Mon, 21 Jul 2025 21:16:34 +0200
Eli Zaretskii <eliz <at> gnu.org> writes:

> Then let's hear from other macOS users: does anyone else who uses
> Emacs on macOS have similar experience wrt the Emacs memory footprint?

+1 I am on MacOS and my Emacs uses 2-4 GB RAM when in light use.

P.S. Not sure if this is relevant but:

  Reproduction steps:

  1. emacs -Q
  2. evaluate in *scratch* the form:
  
     (dotimes (x 1000)
       (let ((frame (make-frame-command)))
         (sleep-for 0.01)
         (delete-frame frame)))
  
  Expected:

    Emacs uses ~60 MB of RAM (again), per the Activity Monitor.
  
  Actual:

    Emacs uses 9.87 GB of RAM (10 minutes later, no change)

Rudy
-- 
"Programming reliably -- must be an activity of an undeniably
mathematical nature […] You see, mathematics is about thinking, and
doing mathematics is always trying to think as well as possible."
--- Edsger W. Dijkstra, 1981

Rudolf Adamkovič <rudolf <at> adamkovic.org> [he/him]
http://adamkovic.org




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79023; Package emacs. (Mon, 21 Jul 2025 19:59:01 GMT) Full text and rfc822 format available.

Message #62 received at 79023 <at> debbugs.gnu.org (full text, mbox):

From: Rudolf Adamkovič <rudolf <at> adamkovic.org>
To: Eli Zaretskii <eliz <at> gnu.org>, Przemysław Alexander
 Kamiński <przemyslaw <at> kaminski.se>
Cc: 79023 <at> debbugs.gnu.org
Subject: Re: bug#79023: 30.1.90; Suspicion of memory leak on
 internal_redisplay (MacOS)
Date: Mon, 21 Jul 2025 21:58:24 +0200
Rudolf Adamkovič <rudolf <at> adamkovic.org> writes:

>      (dotimes (x 1000)
>        (let ((frame (make-frame-command)))
>          (sleep-for 0.01)
>          (delete-frame frame)))

Okay, while on it....

I did this for 100 frames with Instruments attached, after suffering
through Apple signing nonsense.  I found that Emacs leaks memory like
there was no tomorrow (401 thousand leaks), but the leaks were too small
to explain 5.22 GB of RAM used, per the Activity Monitor.  So, I tried
the Allocation instruments, in addition to Leaks, and indeed, and the
code above resulted in 1098 allocations of 4.72 MB, totaling ~5.18 GB,
and they are all like these:

1 0x4432b0000 VM: IOSurface 01:22.610.316 • 4,72 MiB Emacs -[EmacsLayer getContext]
2 0x442df8000 VM: IOSurface 01:22.575.202 • 4,72 MiB Emacs -[EmacsLayer getContext]
3 0x442940000 VM: IOSurface 01:22.509.260 • 4,72 MiB Emacs -[EmacsLayer getContext]
4 0x442488000 VM: IOSurface 01:22.471.821 • 4,72 MiB Emacs -[EmacsLayer getContext]
5 0x441fd0000 VM: IOSurface 01:22.422.630 • 4,72 MiB Emacs -[EmacsLayer getContext]

There are other allocations, of course, but these explain most of the
memory pressure.  The memory stays allocated even after waiting for 15
minutes, doing nothing.

Rudy
-- 
"The introduction of suitable abstractions is our only mental aid to
organize and master complexity."
--- Edsger Wybe Dijkstra, 1930-2002

Rudolf Adamkovič <rudolf <at> adamkovic.org> [he/him]
http://adamkovic.org




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79023; Package emacs. (Mon, 21 Jul 2025 23:34:02 GMT) Full text and rfc822 format available.

Message #65 received at 79023 <at> debbugs.gnu.org (full text, mbox):

From: Rudolf Adamkovič <rudolf <at> adamkovic.org>
To: Eli Zaretskii <eliz <at> gnu.org>, Przemysław Alexander
 Kamiński <przemyslaw <at> kaminski.se>
Cc: 79023 <at> debbugs.gnu.org
Subject: Re: bug#79023: 30.1.90; Suspicion of memory leak on
 internal_redisplay (MacOS)
Date: Tue, 22 Jul 2025 01:33:45 +0200
[Message part 1 (text/plain, inline)]
Rudolf Adamkovič <rudolf <at> adamkovic.org> writes:

> [...], and indeed, and the code above resulted in 1098 allocations of
> 4.72 MB, totaling ~5.18 GB, and they are all like these: [...]

Okay, I could not let go before sleep and investigated further.  See the
attached patch.  With it, the never-freed 5.18 GB of RAM is fixed for:

(dotimes (x 1000)
  (let ((frame (make-frame-command)))
    (sleep-for 0.01)
    (delete-frame frame)))

P.S. The remaining 5.22 - 5.13 ~= 100 MB is wasted due to bugs elsewhere.

Rudy
[0001-NS-Release-EmacsView-and-EmacsLayer-when-deallocatin.patch (text/x-patch, attachment)]
[Message part 3 (text/plain, inline)]
-- 
"Logic is a science of the necessary laws of thought, without which no
employment of the understanding and the reason takes place."
--- Immanuel Kant, 1785

Rudolf Adamkovič <rudolf <at> adamkovic.org> [he/him]
http://adamkovic.org

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79023; Package emacs. (Tue, 22 Jul 2025 12:40:02 GMT) Full text and rfc822 format available.

Message #68 received at 79023 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Rudolf Adamkovič <rudolf <at> adamkovic.org>
Cc: 79023 <at> debbugs.gnu.org, przemyslaw <at> kaminski.se
Subject: Re: bug#79023: 30.1.90; Suspicion of memory leak on
 internal_redisplay (MacOS)
Date: Tue, 22 Jul 2025 15:38:56 +0300
> From: Rudolf Adamkovič <rudolf <at> adamkovic.org>
> Cc: 79023 <at> debbugs.gnu.org
> Date: Mon, 21 Jul 2025 21:16:34 +0200
> 
> Eli Zaretskii <eliz <at> gnu.org> writes:
> 
> > Then let's hear from other macOS users: does anyone else who uses
> > Emacs on macOS have similar experience wrt the Emacs memory footprint?
> 
> +1 I am on MacOS and my Emacs uses 2-4 GB RAM when in light use.
> 
> P.S. Not sure if this is relevant but:
> 
>   Reproduction steps:
> 
>   1. emacs -Q
>   2. evaluate in *scratch* the form:
>   
>      (dotimes (x 1000)
>        (let ((frame (make-frame-command)))
>          (sleep-for 0.01)
>          (delete-frame frame)))
>   
>   Expected:
> 
>     Emacs uses ~60 MB of RAM (again), per the Activity Monitor.

FTR: that's what I see here (not on macOS).

So this is definitely macOS-specific.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79023; Package emacs. (Wed, 23 Jul 2025 15:01:01 GMT) Full text and rfc822 format available.

Message #71 received at 79023 <at> debbugs.gnu.org (full text, mbox):

From: Przemysław Alexander Kamiński
 <przemyslaw <at> kaminski.se>
To: Rudolf Adamkovič <rudolf <at> adamkovic.org>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 79023 <at> debbugs.gnu.org
Subject: Re: bug#79023: 30.1.90; Suspicion of memory leak on
 internal_redisplay (MacOS)
Date: Wed, 23 Jul 2025 17:00:31 +0200
[Message part 1 (text/plain, inline)]
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





[render_block.patch (application/octet-stream, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79023; Package emacs. (Tue, 29 Jul 2025 23:33:01 GMT) Full text and rfc822 format available.

Message #74 received at 79023 <at> debbugs.gnu.org (full text, mbox):

From: Rudolf Adamkovič <rudolf <at> adamkovic.org>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 79023 <at> debbugs.gnu.org, przemyslaw <at> kaminski.se
Subject: Re: bug#79023: 30.1.90; Suspicion of memory leak on
 internal_redisplay (MacOS)
Date: Wed, 30 Jul 2025 01:32:09 +0200
Eli Zaretskii <eliz <at> gnu.org> writes:

> So this is definitely macOS-specific.

Eli, what are the next steps here?

The problem has been found, reproduced, analyzed, measured, patched, and
re-measured.  All that was done on the current MacOS.  I did not test on
GNUstep, as I do not have it installed.

P.S. I also have another NS patch waiting since March 2025 in bug#77062.

Rudy
-- 
"I love deadlines.  I love the whooshing noise they make as they go by."
--- Douglas Adams, The Salmon of Doubt, 2002

Rudolf Adamkovič <rudolf <at> adamkovic.org> [he/him]
http://adamkovic.org




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79023; Package emacs. (Wed, 30 Jul 2025 11:59:02 GMT) Full text and rfc822 format available.

Message #77 received at 79023 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Rudolf Adamkovič <rudolf <at> adamkovic.org>
Cc: 79023 <at> debbugs.gnu.org, przemyslaw <at> kaminski.se
Subject: Re: bug#79023: 30.1.90; Suspicion of memory leak on
 internal_redisplay (MacOS)
Date: Wed, 30 Jul 2025 14:58:30 +0300
> From: Rudolf Adamkovič <rudolf <at> adamkovic.org>
> Cc: przemyslaw <at> kaminski.se, 79023 <at> debbugs.gnu.org
> Date: Wed, 30 Jul 2025 01:32:09 +0200
> 
> Eli Zaretskii <eliz <at> gnu.org> writes:
> 
> > So this is definitely macOS-specific.
> 
> Eli, what are the next steps here?

As usual:

 . someone should post a patch
 . macOS users should run with the patch for a while and provide feedback
 . interested individuals should actively and routinely request feedback
 . after some time, we install the patch with whatever changes it accrues

AFAIU, in this case what we should do now is more testing on more
relevant platforms, and Someone™ should volunteer to track the
testing and collect feedback/make changes to the patch, until we
decide it's tested enough.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79023; Package emacs. (Mon, 04 Aug 2025 18:11:01 GMT) Full text and rfc822 format available.

Message #80 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Przemysław Alexander Kamiński
 <przemyslaw <at> kaminski.se>
To: bug-gnu-emacs <at> gnu.org
Subject: Re: 30.1.90; Suspicion of memory leak on internal_redisplay (MacOS)
Date: Mon, 04 Aug 2025 20:10:03 +0200
[Message part 1 (text/plain, inline)]
I'm attaching the patch that looks promising (from local instrumentation):

Changes:
- render_block mechanism when doing "inner" run loops
- don't CGContextFlush manually (documentation recommends to leave
  window renderer to handle that)
- some small fixes in releases (toolbar)
- niling Emacs' frame struct on window dealloc - it should be garbagged
  but it seems something is still attached to the ref and cannot be GCed

Known issues:
- Can't get resizing as it's chicken-and-egg problem - drag redraws and
redraw reads on socket (which blocks redraws)

Other remarks:
- Increasing number of buffers in "double buffering" prevents leaks and
  memory allocation, but I didn't include it in the patch (e.g. not
  array of 2, but array of 4 or 6)

Best,
Przemysław Alexander Kamiński

[ns.patch (text/x-patch, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79023; Package emacs. (Mon, 11 Aug 2025 13:37:02 GMT) Full text and rfc822 format available.

Message #83 received at 79023 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Przemysław Alexander Kamiński
 <alexander <at> kaminski.se>
Cc: rudolf <at> adamkovic.org, 79023 <at> debbugs.gnu.org
Subject: Re: bug#79023: 30.1.90; Suspicion of memory leak on
 internal_redisplay (MacOS)
Date: Mon, 11 Aug 2025 16:36:27 +0300
> From: Przemysław Alexander Kamiński
>  <alexander <at> kaminski.se>
> Cc: 79023 <at> debbugs.gnu.org
> Date: Mon, 11 Aug 2025 14:09:21 +0200
> 
> 
> I was doing some allocation debugging (it's a build with render block &
> release fixes). It seems I found the problem (30 minute non -Q instance).
> 
>  654.03 MB      69.0%	44835	 	macfont_list
>  654.03 MB      69.0%	44835	 	 font_list_entities
>  654.03 MB      69.0%	44835	 	  font_find_for_lface
>  489.50 MB      51.6%	44541	 	   fontset_find_font
>  489.50 MB      51.6%	44541	 	    fontset_font
>  489.50 MB      51.6%	44541	 	     face_for_char
>  305.78 MB      32.2%	5658	 	      FACE_FOR_CHAR
>  179.89 MB      18.9%	172	 	      FACE_FOR_CHAR
>  164.53 MB      17.3%	294	 	   font_load_for_lface
> 
> I have approx. 500 different fonts which I suppose would explain 10KB
> per allocation. I will check if I can release those cleanly.

This is supposed to cons a list (a Lisp_Object) of relevant fonts,
which is then reclaimed by GC after face_for_char returns (because
there are no references to it).  Is that not what happens on macOS?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79023; Package emacs. (Mon, 11 Aug 2025 15:11:02 GMT) Full text and rfc822 format available.

Message #86 received at 79023 <at> debbugs.gnu.org (full text, mbox):

From: Przemysław Alexander Kamiński
 <alexander <at> kaminski.se>
To: Eli Zaretskii <eliz <at> gnu.org>, Rudolf Adamkovič
 <rudolf <at> adamkovic.org>
Cc: 79023 <at> debbugs.gnu.org
Subject: Re: bug#79023: 30.1.90; Suspicion of memory leak on
 internal_redisplay (MacOS)
Date: Mon, 11 Aug 2025 14:09:21 +0200
I was doing some allocation debugging (it's a build with render block &
release fixes). It seems I found the problem (30 minute non -Q instance).

 654.03 MB      69.0%	44835	 	macfont_list
 654.03 MB      69.0%	44835	 	 font_list_entities
 654.03 MB      69.0%	44835	 	  font_find_for_lface
 489.50 MB      51.6%	44541	 	   fontset_find_font
 489.50 MB      51.6%	44541	 	    fontset_font
 489.50 MB      51.6%	44541	 	     face_for_char
 305.78 MB      32.2%	5658	 	      FACE_FOR_CHAR
 179.89 MB      18.9%	172	 	      FACE_FOR_CHAR
 164.53 MB      17.3%	294	 	   font_load_for_lface

I have approx. 500 different fonts which I suppose would explain 10KB
per allocation. I will check if I can release those cleanly.

Best,
Przemysław Alexander Kamiński
--

Pointers are real. They’re what the hardware understands. Somebody has
to deal with them. You can’t just place a LISP book on top of an x86
chip and hope that the hardware learns about lambda calculus by osmosis.

  -- James Mickens "The Night Watch"




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79023; Package emacs. (Mon, 11 Aug 2025 15:53:01 GMT) Full text and rfc822 format available.

Message #89 received at 79023 <at> debbugs.gnu.org (full text, mbox):

From: Przemysław Alexander Kamiński
 <alexander <at> kaminski.se>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: rudolf <at> adamkovic.org, 79023 <at> debbugs.gnu.org
Subject: Re: bug#79023: 30.1.90; Suspicion of memory leak on
 internal_redisplay (MacOS)
Date: Mon, 11 Aug 2025 17:15:22 +0200
On Mon, Aug 11, 2025 at 16:36:27 (+0300), Eli Zaretskii wrote:

> This is supposed to cons a list (a Lisp_Object) of relevant fonts,
> which is then reclaimed by GC after face_for_char returns (because
> there are no references to it).  Is that not what happens on macOS?

No, and I think it was designed like that but a bug creeped in.

Function macfont_create_family_with_symbol (macfont.m) uses
symbol-to-font cache, but it seems that cache is set only when pat_desc exists.
Not sure why it's like that, but if that's not on purpose it would
explain why reporting was inconsistent.

I'm not seeing these allocations anymore at all. I started also changing 
ns_can_use_native_image_api function (as it resulted in huge amount of
small allocs). With those two changes I've seen merely 2MiB allocation after my
eshell colorful "fd" listing test - and it seems a legit one (some hook fired).

I need to clean up the code and split patches in smaller ones, hope to
do have that soon.

Best,
Przemysław Alexander Kamiński




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79023; Package emacs. (Mon, 11 Aug 2025 18:48:02 GMT) Full text and rfc822 format available.

Message #92 received at 79023 <at> debbugs.gnu.org (full text, mbox):

From: Przemysław Alexander Kamiński
 <alexander <at> kaminski.se>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: rudolf <at> adamkovic.org, 79023 <at> debbugs.gnu.org
Subject: Re: bug#79023: 30.1.90; Suspicion of memory leak on
 internal_redisplay (MacOS)
Date: Mon, 11 Aug 2025 20:47:44 +0200
[Message part 1 (text/plain, inline)]
I'm attaching 6 patches (for easy review/scrutiny/integration).
Those patches that I marked as tested was used by me for >1 week.

* render_block_small.patch (significant impact, tested):

This is similar patch to previous one, but it's minimal. It's crucial
to avoid "blink" redraws.
Still breaks smooth resizing, but frame-resize-pixelwise set to true
makes it unnoticable.

* cache_all_font_results.patch (significant impact, requires testing):

This one prevents huge leak. I was trying to debug emacs-mac version (which
has very deep traces for allocations, more 256 deep, which is limit for
Instrumentations).

That led to full malloc logging and discovery that macfont listings were
allocating plenty of font-related data. Some of it it never cleared.

I didn't test it and worry that caching "null" result might introduce
some bugs, but it was hundreds of megabytes of allocations on -Q instance.

* dont_flush_cg.patch (medium impact, tested):

Based on documentation of CGContextFlush it should seldom be used, as
it's much better to give OS possibility to decide when to flush. It
prevents non-needed renders (and allocations etc.)

* misc_releases.patch (small-mid impact, tested):

This one is based on Rudolf Adamkovič patch with some minor extra
releases and adjustments
(like releasing an object before setting it to nil ;))

* ns_native_api_dict.patch (small-mid impact, needs testing):

A small leak, but modified function had ~600_000 allocations after very
short test runs. Seems like it wasted a lot of power, so I decided it
should be checking dictionary hydrated at start and queried later
instead of checking during runtime.

I believe that high NSString allocation amount was indirectly caused by
using autorelease pools.

* nullify_frame.patch (small impact, tested):

releases reference to a frame, as I've found traces in which resources
were left behind, small leak.

---

Fingers crossed that patches go through ;-)

[nullify_frame.patch (text/x-patch, attachment)]
[ns_native_api_dict.patch (text/x-patch, attachment)]
[render_block_small.patch (text/x-patch, attachment)]
[cache_all_font_results.patch (text/x-patch, attachment)]
[dont_flush_cg.patch (text/x-patch, attachment)]
[misc_releases.patch (text/x-patch, attachment)]
[Message part 8 (text/plain, inline)]
Best,
Przemysław Alexander Kamiński

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79023; Package emacs. (Tue, 12 Aug 2025 00:08:02 GMT) Full text and rfc822 format available.

Message #95 received at 79023 <at> debbugs.gnu.org (full text, mbox):

From: Rudolf Adamkovič <rudolf <at> adamkovic.org>
To: Przemysław Alexander Kamiński
 <alexander <at> kaminski.se>, Eli Zaretskii <eliz <at> gnu.org>
Cc: 79023 <at> debbugs.gnu.org
Subject: Re: bug#79023: 30.1.90; Suspicion of memory leak on
 internal_redisplay (MacOS)
Date: Tue, 12 Aug 2025 02:07:04 +0200
Przemysław Alexander Kamiński <alexander <at> kaminski.se> writes:

> I'm attaching 6 patches (for easy review/scrutiny/integration).

This is fantastic!  When I was fixing view/layer leaks, I saw lots of
other leaks, and the word "font" certainly caught my attention. :) I
remember thinking, "I hope we [the community] will fix all these next,
but let me first focus on the biggest leak [on my system]".

So, I am super-happy someone is doing more!  The NS port badly needs
some serious love, or replacement.  Its pixelated tool bar icons with
white background in dark theme, barely responsive C-g, memory leaks,
freezes, and crashes... scream "unmaintained".  That is where we are.

On my machine, NS often freezes, even `emacs -Q', when closing a frame
with the mouse, using the standard WM "red circle" button.  I have no
reproducer, unfortunately.  But, as a result, I close frames strictly
with the keyboard, after losing edits multiple times.  Similarly, when
native compilation is doing its thing, Emacs is unusable because C-g is
99% ignored, even worse than normal, so I wait.  The list goes on...

So, thank you for improving the NS port!

Rudy
-- 
"Mathematics takes us still further from what is human into the region
of absolute necessity, to which not only the actual world, but every
possible world, must conform."
--- Bertrand Russell, 1902

Rudolf Adamkovič <rudolf <at> adamkovic.org> [he/him]
http://adamkovic.org




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79023; Package emacs. (Tue, 12 Aug 2025 04:47:01 GMT) Full text and rfc822 format available.

Message #98 received at 79023 <at> debbugs.gnu.org (full text, mbox):

From: "Paul D. Nelson" <ultrono <at> gmail.com>
To: Przemysław Alexander Kamiński
 <alexander <at> kaminski.se>
Cc: rudolf <at> adamkovic.org, eliz <at> gnu.org, 79023 <at> debbugs.gnu.org
Subject: Re: bug#79023: 30.1.90; Suspicion of memory leak on
 internal_redisplay (MacOS)
Date: Tue, 12 Aug 2025 06:46:38 +0200
Przemysław Alexander Kamiński <alexander <at> kaminski.se> writes:

> I'm attaching 6 patches (for easy review/scrutiny/integration).
> Those patches that I marked as tested was used by me for >1 week.

I tried applying the patches for testing, but there were some clashes,
e.g., nullify_frame.patch and misc_releases.patch both the modify the
end of dealloc in nsterm.m, but the modifications do not stack.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79023; Package emacs. (Tue, 12 Aug 2025 06:05:02 GMT) Full text and rfc822 format available.

Message #101 received at 79023 <at> debbugs.gnu.org (full text, mbox):

From: Przemysław Alexander Kamiński
 <alexander <at> kaminski.se>
To: Rudolf Adamkovič <rudolf <at> adamkovic.org>, Eli Zaretskii
 <eliz <at> gnu.org>
Cc: 79023 <at> debbugs.gnu.org
Subject: Re: bug#79023: 30.1.90; Suspicion of memory leak on
 internal_redisplay (MacOS)
Date: Tue, 12 Aug 2025 08:04:10 +0200
On Tue, Aug 12, 2025 at 02:07:04 (+0200), Rudolf Adamkovič wrote:
> Przemysław Alexander Kamiński <alexander <at> kaminski.se> writes:
>> I'm attaching 6 patches (for easy review/scrutiny/integration).
>
> This is fantastic!  When I was fixing view/layer leaks, I saw lots of
> other leaks, and the word "font" certainly caught my attention. :) I
> remember thinking, "I hope we [the community] will fix all these next,
> but let me first focus on the biggest leak [on my system]".

I'll note that I found many red herrings when looking for leaks. MacOS default
instrumentation tools are not recording stacks bigger than 256.
NS version often has much bigger ones and emacs-mac relies on recursion
(instead of start/stop) so the stacks are even deeper.

Only after enabling MallockStackLogging at running the trace data is
more visible. I have a Makefile that sets Malloc logging variable like this:

malloc: export MallocStackLogging := 1
malloc: export MallocStackLoggingNoCompact := 1
malloc: export MallocScribble := 1
malloc: export MallocPreScribble := 1
malloc:
	$(EMACS_SOURCE_ROOT)/src/emacs -Q

Visibility is much higher. I'm starting to wonder if I shouldn't
write documentation about debugging techniques on MacOS, so more people
could help - I suppose that many contributors know this trick, but I
just started writing C last week ;)

> So, I am super-happy someone is doing more!  The NS port badly needs
> some serious love, or replacement.  Its pixelated tool bar icons with
> white background in dark theme, barely responsive C-g, memory leaks,
> freezes, and crashes... scream "unmaintained".  That is where we are.

Render block (i.e. no ability to start new event processing while
keyboard input or socket read is happening) should help with some of the
issues.

C-g problem bothers me the most. It should be processed ASAP. Both
render-blocking wrappers are in functions that prioritize processing
them C-g so it might be better. If not - that will be my next
"minor change". I'll start a new thread od emacs-devel about it.

I wonder if shell-running sleep could work as a reproducer? I don't have
Linux anywhere, but what's the expectation, that C-g would kill the
process ASAP?

As for crashes - understanding much more about what is happening in
Emacs I've seen one and it was unsurprising one - accepting input while
input was blocked (from mouse!). I didn't pay too much of an attention
but this most likely still can happen.

> On my machine, NS often freezes, even `emacs -Q', when closing a frame
> with the mouse, using the standard WM "red circle" button.

Experienced same. Checked this on 10h instance - no issues. I think it
is resolved by nullifying patch. IMO reusing frames instead of creating
new ones was simple expensive and nullyfing reference to the frame
delegated cleanup to much faster (and thorough) OS.

> So, thank you for improving the NS port!

Even though I tried to quit it many times (mostly of boredom) I've been
using Emacs for ~25 years. I'm happy to be able to give something back
and make it better experience.

Sloving non-trivial issue in a decades old software with minimal
knowledge of used technology and architecture is also something that I
consider a welcome "win", and ego points can not be overlooked ;-)

Yet I'd like to thank you Rudy, as your enthusiasm helped me look into
those issues. I tend to avoid zero-feedback problems as it usually mean
an art for art's sake.

Eli, also thank your for gently steering me out of the rabbit hole. You
have great people skill.

Best,
Przemysław Alexander Kamiński
-- 

Pointers are real. They’re what the hardware understands. Somebody has
to deal with them. You can’t just place a LISP book on top of an x86
chip and hope that the hardware learns about lambda calculus by osmosis.

  -- James Mickens "The Night Watch"




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79023; Package emacs. (Tue, 12 Aug 2025 06:11:02 GMT) Full text and rfc822 format available.

Message #104 received at 79023 <at> debbugs.gnu.org (full text, mbox):

From: Przemysław Alexander Kamiński
 <alexander <at> kaminski.se>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: rudolf <at> adamkovic.org, 79023 <at> debbugs.gnu.org
Subject: Re: bug#79023: 30.1.90; Suspicion of memory leak on
 internal_redisplay (MacOS)
Date: Tue, 12 Aug 2025 08:10:31 +0200
[Message part 1 (text/plain, inline)]
Version 2 of API dictionary. Previous one didn't take into account that
some sub-processes might not initialize ns_term while still wanting to
know native support for images which crashed subprocesses.

This one initializes upon first usage (and is retained throughout lifetime).

With all patches combined:
Mem(Init->10h uptime->GC) - Mem(Init) = +- 1MiB

Best,
Przemysław Alexander Kamiński
-- 

Pointers are real. They’re what the hardware understands. Somebody has
to deal with them. You can’t just place a LISP book on top of an x86
chip and hope that the hardware learns about lambda calculus by osmosis.

  -- James Mickens "The Night Watch"

[ns_native_api_dict_0002.patch (text/x-patch, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79023; Package emacs. (Tue, 12 Aug 2025 06:26:01 GMT) Full text and rfc822 format available.

Message #107 received at 79023 <at> debbugs.gnu.org (full text, mbox):

From: Przemysław Alexander Kamiński
 <alexander <at> kaminski.se>
To: "Paul D. Nelson" <ultrono <at> gmail.com>
Cc: rudolf <at> adamkovic.org, eliz <at> gnu.org, 79023 <at> debbugs.gnu.org
Subject: Re: bug#79023: 30.1.90; Suspicion of memory leak on
 internal_redisplay (MacOS)
Date: Tue, 12 Aug 2025 08:24:49 +0200
[Message part 1 (text/plain, inline)]
On Tue, Aug 12, 2025 at 06:46:38 (+0200), Paul D. Nelson wrote:

> Przemysław Alexander Kamiński <alexander <at> kaminski.se> writes:
>
>> I'm attaching 6 patches (for easy review/scrutiny/integration).
>> Those patches that I marked as tested was used by me for >1 week.
>
> I tried applying the patches for testing, but there were some clashes,
> e.g., nullify_frame.patch and misc_releases.patch both the modify the
> end of dealloc in nsterm.m, but the modifications do not stack.

Yes, that's on purpose. I didn't want them to be considered together.
It's also easier for me to manage through Jujutsu front as merge commit
is regenerated after patch commit was changed.

I'm attaching combined patch for convenience. It already includes
ns_native_api_dict_0002.patch (0001 was crashing compilation
subprocesses).

Best,
Przemysław Alexander Kamiński
-- 

Pointers are real. They’re what the hardware understands. Somebody has
to deal with them. You can’t just place a LISP book on top of an x86
chip and hope that the hardware learns about lambda calculus by osmosis.

  -- James Mickens "The Night Watch"

[combined_0001.patch (text/x-patch, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79023; Package emacs. (Tue, 12 Aug 2025 12:13:02 GMT) Full text and rfc822 format available.

Message #110 received at 79023 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Przemysław Alexander Kamiński
 <alexander <at> kaminski.se>
Cc: rudolf <at> adamkovic.org, 79023 <at> debbugs.gnu.org
Subject: Re: bug#79023: 30.1.90; Suspicion of memory leak on
 internal_redisplay (MacOS)
Date: Tue, 12 Aug 2025 15:11:51 +0300
> From: Przemysław Alexander Kamiński
>  <alexander <at> kaminski.se>
> Cc: 79023 <at> debbugs.gnu.org
> Date: Tue, 12 Aug 2025 08:04:10 +0200
> 
> I'm starting to wonder if I shouldn't write documentation about
> debugging techniques on MacOS, so more people could help

If you do, please propose that as patches to etc/DEBUG, preferably in
a separate new section.

Thanks.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79023; Package emacs. (Tue, 12 Aug 2025 14:13:02 GMT) Full text and rfc822 format available.

Message #113 received at 79023 <at> debbugs.gnu.org (full text, mbox):

From: Przemysław Alexander Kamiński
 <przemyslaw <at> kaminski.se>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: rudolf <at> adamkovic.org, 79023 <at> debbugs.gnu.org
Subject: Re: bug#79023: 30.1.90; Suspicion of memory leak on
 internal_redisplay (MacOS)
Date: Tue, 12 Aug 2025 16:12:31 +0200
[Message part 1 (text/plain, inline)]
- ns_native_api dictionary update, hopefully final
- macfont_list_cache_0001.patch adds a spec-to-list cache - I noticed
  that it still is leaking (probably with packages that are running
  results in a subprocess)

[macfont_list_cache_0001.patch (text/x-patch, attachment)]
[ns_native_api_dict_0003.patch (text/x-patch, attachment)]
[Message part 4 (text/plain, inline)]
Best,
Przemysław Alexander Kamiński

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79023; Package emacs. (Wed, 27 Aug 2025 08:08:01 GMT) Full text and rfc822 format available.

Message #116 received at 79023 <at> debbugs.gnu.org (full text, mbox):

From: Przemysław Alexander Kamiński
 <alexander <at> kaminski.se>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: rudolf <at> adamkovic.org, 79023 <at> debbugs.gnu.org
Subject: Re: bug#79023: 30.1.90; Suspicion of memory leak on
 internal_redisplay (MacOS)
Date: Wed, 27 Aug 2025 10:07:19 +0200
Eli,

should I maybe break off those 6 patches and submit them to emacs-devel
for easier integration?

Best,
Przemysław Alexander Kamiński




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79023; Package emacs. (Wed, 27 Aug 2025 12:36:02 GMT) Full text and rfc822 format available.

Message #119 received at 79023 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Przemysław Alexander Kamiński
 <alexander <at> kaminski.se>, Alan Third <alan <at> idiocy.org>,
 Gerd Möllmann <gerd.moellmann <at> gmail.com>
Cc: rudolf <at> adamkovic.org, 79023 <at> debbugs.gnu.org
Subject: Re: bug#79023: 30.1.90; Suspicion of memory leak on
 internal_redisplay (MacOS)
Date: Wed, 27 Aug 2025 15:35:07 +0300
> From: Przemysław Alexander Kamiński
>  <alexander <at> kaminski.se>
> Cc: rudolf <at> adamkovic.org, 79023 <at> debbugs.gnu.org
> Date: Wed, 27 Aug 2025 10:07:19 +0200
> 
> Eli,
> 
> should I maybe break off those 6 patches and submit them to emacs-devel
> for easier integration?

No, we should ask relevant people (CC'ed) to please review the patches
and comment on them.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79023; Package emacs. (Wed, 27 Aug 2025 12:54:01 GMT) Full text and rfc822 format available.

Message #122 received at 79023 <at> debbugs.gnu.org (full text, mbox):

From: Gerd Möllmann <gerd.moellmann <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: Przemysław Alexander Kamiński
 <alexander <at> kaminski.se>, rudolf <at> adamkovic.org, Alan Third <alan <at> idiocy.org>,
 79023 <at> debbugs.gnu.org
Subject: Re: bug#79023: 30.1.90; Suspicion of memory leak on
 internal_redisplay (MacOS)
Date: Wed, 27 Aug 2025 14:52:53 +0200
Eli Zaretskii <eliz <at> gnu.org> writes:

>> From: Przemysław Alexander Kamiński
>>  <alexander <at> kaminski.se>
>> Cc: rudolf <at> adamkovic.org, 79023 <at> debbugs.gnu.org
>> Date: Wed, 27 Aug 2025 10:07:19 +0200
>> 
>> Eli,
>> 
>> should I maybe break off those 6 patches and submit them to emacs-devel
>> for easier integration?
>
> No, we should ask relevant people (CC'ed) to please review the patches
> and comment on them.

Sorry, but I'll have to pass.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79023; Package emacs. (Sun, 31 Aug 2025 19:47:02 GMT) Full text and rfc822 format available.

Message #125 received at 79023 <at> debbugs.gnu.org (full text, mbox):

From: Alan Third <alan <at> idiocy.org>
To: Przemysław Alexander Kamiński <alexander <at> kaminski.se>
Cc: rudolf <at> adamkovic.org, Eli Zaretskii <eliz <at> gnu.org>, 79023 <at> debbugs.gnu.org
Subject: Re: bug#79023: 30.1.90; Suspicion of memory leak on
 internal_redisplay (MacOS)
Date: Sun, 31 Aug 2025 20:46:03 +0100
On Mon, Aug 11, 2025 at 08:47:44PM +0200, Przemysław Alexander Kamiński wrote:
> 
> I'm attaching 6 patches (for easy review/scrutiny/integration).
> Those patches that I marked as tested was used by me for >1 week.
> 
> * render_block_small.patch (significant impact, tested):
> 
> This is similar patch to previous one, but it's minimal. It's crucial
> to avoid "blink" redraws.
> Still breaks smooth resizing, but frame-resize-pixelwise set to true
> makes it unnoticable.

I'm not convinced this is the way to do this. I still think a better
solution would be to move the redisplay call to the EmacsLayer's
'display' method. As I understand it the system should only call that
method when it actually wants to display the output. Is that called
too often?

> * cache_all_font_results.patch (significant impact, requires testing):
> 
> This one prevents huge leak. I was trying to debug emacs-mac version (which
> has very deep traces for allocations, more 256 deep, which is limit for
> Instrumentations).
> 
> That led to full malloc logging and discovery that macfont listings were
> allocating plenty of font-related data. Some of it it never cleared.
> 
> I didn't test it and worry that caching "null" result might introduce
> some bugs, but it was hundreds of megabytes of allocations on -Q instance.

I can't comment on this as I have no idea how macfont.m works. Perhaps
some of the people working on the Mac port can help.

> * dont_flush_cg.patch (medium impact, tested):
> 
> Based on documentation of CGContextFlush it should seldom be used, as
> it's much better to give OS possibility to decide when to flush. It
> prevents non-needed renders (and allocations etc.)

See notes below.

> * misc_releases.patch (small-mid impact, tested):
> 
> This one is based on Rudolf Adamkovič patch with some minor extra
> releases and adjustments
> (like releasing an object before setting it to nil ;))

EmacsLayer is only used on Cocoa, and only on certain versions, so
anything that references it needs to be limited. Look at the #if
before the definition of EmacsLayer.

> * ns_native_api_dict.patch (small-mid impact, needs testing):
> 
> A small leak, but modified function had ~600_000 allocations after very
> short test runs. Seems like it wasted a lot of power, so I decided it
> should be checking dictionary hydrated at start and queried later
> instead of checking during runtime.
> 
> I believe that high NSString allocation amount was indirectly caused by
> using autorelease pools.

LGTM except for the same problem as above. You'll need to look at the
#if or #ifdefs around the code and ensure the new code is correctly
excluded when building on GNUstep.

I think you also removed a #if but left the associated #else and
#endif, although I could be wrong about that.

> * nullify_frame.patch (small impact, tested):
> 
> releases reference to a frame, as I've found traces in which resources
> were left behind, small leak.

This one is funny as emacsframe is a pointer to a "struct frame" and
we're not using garbage collection in NS so I don't see how simply
having a reference in a released object can prevent that struct from
being properly freed. Am I missing something?

> +  /* Don't reuse inner - cleanup is robust enough */
> +  emacsframe = nil;
> +

And I don't understand the comment.


> diff --git a/src/nsterm.m b/src/nsterm.m
> index b006b4d5dd..057d876a35 100644
> --- a/src/nsterm.m
> +++ b/src/nsterm.m
> @@ -9033,7 +9033,6 @@
> 
>  #if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
>    CGContextRef context = [(EmacsLayer *)[self layer] getContext];
> -  CGContextFlush (context);
> 
>    double scale = [[self window] backingScaleFactor];
>    int bpp = CGBitmapContextGetBitsPerPixel (context) / 8;

Immediately after this flush we access the pixels directly in the
buffer, so we *require* that all drawing actions in the context have
been completed, otherwise we risk doing actions out of order.
Therefore this flush is required.

> @@ -10994,7 +10993,6 @@
>    if (!context)
>      return;
> 
> -  CGContextFlush (context);
>    CGContextRelease (context);
>    context = NULL;

This one is probably superfluous as the CGContextRelease will probably
do the flush itself, but I don't know that for sure and we definitely
need it flushed before we can perform the next action, so I don't see
this as a problem.

Aside from that I think there was maybe some non-GNU-standard style C
in the nsimage patch, but I'm not entirely clear how it should look
myself.

Thanks!
-- 
Alan Third




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79023; Package emacs. (Sun, 07 Sep 2025 15:05:02 GMT) Full text and rfc822 format available.

Message #128 received at 79023 <at> debbugs.gnu.org (full text, mbox):

From: Przemysław Alexander Kamiński
 <alexander <at> kaminski.se>
To: Alan Third <alan <at> idiocy.org>
Cc: rudolf <at> adamkovic.org, Eli Zaretskii <eliz <at> gnu.org>, 79023 <at> debbugs.gnu.org
Subject: Re: bug#79023: 30.1.90; Suspicion of memory leak on
 internal_redisplay (MacOS)
Date: Sun, 07 Sep 2025 17:03:38 +0200
Hi Alan!

On Sun, Aug 31, 2025 at 20:46:03 (+0100), Alan Third wrote:
>> * render_block_small.patch (significant impact, tested):
>> 
>> This is similar patch to previous one, but it's minimal. It's crucial
>> to avoid "blink" redraws.
>> Still breaks smooth resizing, but frame-resize-pixelwise set to true
>> makes it unnoticable.

I start to hope this patch won't have to be implemented. If there are no
allocations (or allocations are reused) then it doesnt matter how fast
they are processed. 

>> * dont_flush_cg.patch (medium impact, tested):
>> 
>> Based on documentation of CGContextFlush it should seldom be used, as
>> it's much better to give OS possibility to decide when to flush. It
>> prevents non-needed renders (and allocations etc.)
>
> See notes below.
>
>> * misc_releases.patch (small-mid impact, tested):
>> 
>> This one is based on Rudolf Adamkovič patch with some minor extra
>> releases and adjustments
>> (like releasing an object before setting it to nil ;))
>
> EmacsLayer is only used on Cocoa, and only on certain versions, so
> anything that references it needs to be limited. Look at the #if
> before the definition of EmacsLayer.

Will look into this, but I started wondering about breaking of Cocoa
code outside. Going through nsterm.m is quite confusing.


>> * ns_native_api_dict.patch (small-mid impact, needs testing):
>> ...
> LGTM except for the same problem as above. You'll need to look at the
> #if or #ifdefs around the code and ensure the new code is correctly
> excluded when building on GNUstep.
>
> I think you also removed a #if but left the associated #else and
> #endif, although I could be wrong about that.

Same.

>> * nullify_frame.patch (small impact, tested):
>> 
>> releases reference to a frame, as I've found traces in which resources
>> were left behind, small leak.
>
> This one is funny as emacsframe is a pointer to a "struct frame" and
> we're not using garbage collection in NS so I don't see how simply
> having a reference in a released object can prevent that struct from
> being properly freed. Am I missing something?
>
>> +  /* Don't reuse inner - cleanup is robust enough */
>> +  emacsframe = nil;
>> +
> And I don't understand the comment.

I patched this comment. It should be "cleanup isn't robust enough".
Releasing emacsframe reference seems to release these -  otherwise there
are still objects that are referencing it.

>> diff --git a/src/nsterm.m b/src/nsterm.m
>> index b006b4d5dd..057d876a35 100644
>> --- a/src/nsterm.m
>> +++ b/src/nsterm.m
>> @@ -9033,7 +9033,6 @@
>> 
>>  #if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
>>    CGContextRef context = [(EmacsLayer *)[self layer] getContext];
>> -  CGContextFlush (context);
>> 
>>    double scale = [[self window] backingScaleFactor];
>>    int bpp = CGBitmapContextGetBitsPerPixel (context) / 8;
>
> Immediately after this flush we access the pixels directly in the
> buffer, so we *require* that all drawing actions in the context have
> been completed, otherwise we risk doing actions out of order.
> Therefore this flush is required.

For context - I'm running this pretty much for couple weeks, and I
haven't observed any issues. The flush is going to be happening every
frame anyways, with it the flush count happens thousands of times.

But, truth be told, I haven't ran graphic heavy workflows (like images,
PDFs, etc.) so it might require more testing in that particular area.

Also I really hope that this could be prevented at all. The problem
isn't memory usage per se, but how allocations are happening.  If
allocations can be put in arenas/zones than none of it actually matters.

> Aside from that I think there was maybe some non-GNU-standard style C
> in the nsimage patch, but I'm not entirely clear how it should look
> myself.

Thanks for bringing this to my attention. I'll look into this, but I'm
at some... other level right now ;) (isolated builds and quick clean
rebuilds, as this kicked me in the back couple times already).

Best,
Przemysław Alexander Kamiński
-- 

Pointers are real. They’re what the hardware understands. Somebody has
to deal with them. You can’t just place a LISP book on top of an x86
chip and hope that the hardware learns about lambda calculus by osmosis.

  -- James Mickens "The Night Watch"




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79023; Package emacs. (Fri, 19 Sep 2025 08:44:04 GMT) Full text and rfc822 format available.

Message #131 received at 79023 <at> debbugs.gnu.org (full text, mbox):

From: Alan Third <alan <at> idiocy.org>
To: Przemysław Alexander Kamiński <alexander <at> kaminski.se>
Cc: rudolf <at> adamkovic.org, Eli Zaretskii <eliz <at> gnu.org>, 79023 <at> debbugs.gnu.org
Subject: Re: bug#79023: 30.1.90; Suspicion of memory leak on
 internal_redisplay (MacOS)
Date: Fri, 19 Sep 2025 09:42:57 +0100
On Sun, Sep 07, 2025 at 05:03:38PM +0200, Przemysław Alexander Kamiński wrote:
> Hi Alan!

Hi Alexander,

To get this moved on, can you please provide a single patch with all
the missed memory releases and we can get that committed to master? I
think we all agree they are needed so there's no point in discussing
them further.

-- 
Alan Third




This bug report was last modified today.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.