[求助] emacs选择文本卡死,内存暴涨

版本: GNU Emacs 28.2 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.34, cairo version 1.17.6) of 2022-09-12

安装方式: pacman -S emacs

复现: emacs -q markdown-mode.el 然后按 C-x h / mark-whole-buffer 然后就卡死了,占住一个cpu然后内存一直涨,这个文件400kb左右。

编辑: 临时解决方案,M-w和C-x h 不会卡了:

(setq select-active-regions 'only) ;; 解决了C-x h卡住,不知道这个有啥影响
(setq x-select-enable-clipboard nil) ;; 解决了M-w卡住,但是不能用系统剪贴板了
  1. emacs -q markdown-mode.el
  2. M-x profiler-start RET cpu RET
  3. C-h
  4. 让 cpu 涨一会儿
  5. M-x profiler-report RET

然后看那个函数耗时最多。

第三步C-x h就卡死了,一直卡到内存满然后被杀

4.5. C-g

Screenshot_20221116_212417

关掉 font-lock-mode 或者切换到 fundamental-mode 再复制如何?

顺带,检测一下文件里有没有非 ASCII 字符

不管是不是如上原因相关,都建议 report-emacs-bug,通知相关的打包者来定位问题。

换成更严格的 -Q 再试一下:

- 1. emacs -q markdown-mode.el
+ 1. emacs -Q markdown-mode.el

有些平台/发行版打包的时候会在 /usr/local/chare/emacs/site-lisp/ 放置一些额外的包,有可能导致问题,例如:gnu emacs 27.1每次启动都提示 Symbol’s value as variable is void: ispell-menu-map-needed - #7,来自 twlz0ne

1 个赞

不行,结果还是一样的,关掉font-lock-mode和fundamental-mode也不行,话说是只有我一个人这样还是大家都这样?

另外 emacs -nw 终端似乎是正常的,只会卡一下,不会和gui一样一直卡死

那就在终端下测,看看是不是同一个问题。

看起来不像是同一个问题 Screenshot_20221117_145051

把 66% 展开呀,不然怎么知道哪里有问题。

最好卡久一点再出报告。

用我的配置测试一下.GitHub - redguardtoo/emacs.d: Fast and robust Emacs setup.

emacs -q markdown-mode.el ,会有:

Screenshot from 2022-11-17 15-09-48

但是自己直接打开文件,使用 mark-whole-buffer,其实并没有这个问题。

终端下是几乎是不卡的

Screenshot_20221117_151956

@kekeimiku @org 自己编译试试看,不要用软件包管理器安装,它们有可能会打补丁或者植入一些额外的包。

又或者打包的环境跟你现在系统存在差异,导致莫名奇妙的问题。我就遇到因为打包平台 SDK 导致 Emacs 28 在我电脑上必崩溃的问题:28.1 不稳定?我刚发生闪退 - #5,来自 twlz0ne

我可以复现,环境和楼主的一样。只要打开一个大文件(我试了 org.el),求值

(progn (set-marker (mark-marker) (point-max)) (setq mark-active t))

这个问题不仅现有版本的emacs,老版本的emacs 同样。 其实 mark-whole-buffer 还会造成更多余下操作卡死 比如:

  1. 对有 babel block 的 org 文件 C-x h 然后 M-q 然后 emacs 卡死 直到 C-g N 次 (可能恢复,也可能一直 hang)。
  2. 对 已经 mark 的大 size (可能几兆 关键是要有上万行)的 buffer 进行 delete-forward-char。直接卡死(看机率 C-g 能恢复)。

macos arm-64 emacs-plus native-comp C-h f org-mode 然后打开 org.el,然后执行mark-whole-buffer 毫无卡顿

今年写插件的性能实测, Elisp的性能排序应该这样排:

  1. GC是Elisp最影响性能的地方, 这也是 blink-search 比 ivy 快的原因, ivy 已经做了渲染优化, 但是遇到超大文件数的时候会触发 GC, 即使 99% 的数据并没有渲染
  2. Elisp语言的执行性能
  3. 多线程

我写 lsp-bridge 的时候就一直在思考这三个问题, 多线程基本上无解。

但是前面两个问题完全是可以解决的:

  1. GC的问题大概率是Emacs诞生的那个时代内存很小, 它默认的策略导致GC太敏感了, 这样一旦遇到超大数据 (比如 rg 或者 lsp) 的时候, GC才是卡顿的罪魁祸首
  2. Elisp语言的执行性能完全可以引入JIT的手段, 可以逻辑提升代码的性能, 同时也不会带来兼容性的问题

分享一下我的测试结论, 但是我最近越来越忙了, 没有时间对GC和JIT动手术了。

2 个赞

我测试了windows版本的,也没啥问题,linux下的无配置的会有问题,带配置的就没问题,一会真得二分大法看看哪里的配置无意间解决了这个问题。

1 个赞