46

我经常定制 Emacs。最近,我在我的 .emacs 配置中添加了一些东西,它偶尔会将我的 CPU 固定在 100%,但我真的不知道它是什么。

如果我按 Cg 多次,最终我会在 minibuffer下方收到一条消息,询问我是否要自动保存文件,然后是否要完全中止 emacs。如果我一直拒绝并一直按 Cg,最终我可以恢复正常运行 emacs。一个小时左右后,它会再次发生。

我可以像现在这样继续前进,评论我最近添加的各种内容,重新启动 emacs,试图缩小罪魁祸首,但进展缓慢。

有没有办法可以直接分析 emacs 以找出占用 CPU 的 lisp 函数?

4

4 回答 4

52

设置debug-on-quitt以便您可以了解 Emacs 正在做什么的建议是一个很好的建议。您可以将其视为使用单个样本进行抽样分析的一种形式:通常您只需要一个样本。


更新:从 24.3 版开始,Emacs 包含两个分析器。中有一个(新的)采样分析器profiler.el,和一个(旧的)仪器分析器在elp.el.

采样分析器在此处记录。使用起来非常简单:

要开始分析,请键入M-x profiler-start。您可以选择按处理器使用情况、内存使用情况或两者进行分析。完成一些工作后,键入M-x profiler-report以显示您选择分析的每个资源的摘要缓冲区。完成分析后,键入M-x profiler-stop.

这是我维护的带有Perforce/Emacs 集成cpu+mem的分析器会话的一些示例输出。我扩展了最顶层的函数 ( ),以便找出CPU 时间和内存使用的来源progn

Function                                            Bytes    %
- progn                                        26,715,850  29%
  - let                                        26,715,850  29%
    - while                                    26,715,850  29%
      - let                                    26,715,850  29%
        - cond                                 26,715,850  29%
          - insert                             26,715,850  29%
            + c-after-change                   26,713,770  29%
            + p4-file-revision-annotate-links       2,080   0%
+ let                                          20,431,797  22%
+ call-interactively                           12,767,261  14%
+ save-current-buffer                          10,005,836  11%
+ while                                         8,337,166   9%
+ p4-annotate-internal                          5,964,974   6%
+ p4-annotate                                   2,821,034   3%
+ let*                                          2,089,810   2%

你可以看到罪魁祸首是c-after-change,所以看起来我可以通过本地绑定inhibit-modification-hookst周围的代码来节省大量的 CPU 时间和内存。


您还可以使用 Emacs Lisp Profiler。这是相当不足的记录:您必须阅读注释以elp.el了解详细信息,但基本上您运行elp-instrument-package以打开具有给定前缀的所有函数的分析,然后elp-results查看结果。

M-x elp-instrument-package RET c- RET这是键入、字体化 4,000 行 C,然后运行elp-results(并使用elp-sort-by-function按调用次数排序)后的一些典型输出:

Function Name                  Call Count  Elapsed Time  Average Time
=============================  ==========  ============  ============
c-skip-comments-and-strings    107         0.0           0.0
c-valid-offset                 78          0.0           0.0
c-set-offset                   68          0.031         0.0004558823
c-end-of-macro                 52          0.0           0.0
c-neutralize-CPP-line          52          0.0           0.0
c-font-lock-invalid-string     20          0.0           0.0
c-set-style-1                  19          0.031         0.0016315789
...

在您的特定情况下,分析器不会立即提供帮助,因为您不知道哪个包有问题。但是,如果您可以做出猜测(或使用debug-on-quit它来确定),那么分析器可以帮助您详细诊断问题。

于 2009-02-20T13:48:56.943 回答
8

你有没有试过:Options->Enter debugger on Quit/C-g?(这是在 emacs22 上)

如果您需要调试 emacs 的启动:使用emacs -q --no-site-file,访问您的.emacssite-start.el或其他),激活菜单项Options->Enter debugger on Quit/C-g,然后是菜单项Emacs-Lisp->Evaluate bufferC-g当它出现冻结时。可能有更简单的方法来做到这一点............

于 2009-02-20T03:41:29.787 回答
6

使用 dope.el,您可以分析整个 .emacs 或在启动时加载的多个 elisp 文件。从www.gnufans.net/~deego/pub/emacspub/lisp-mine/dope/下载

M-x dope-quick-start将显示一个小介绍教程。

编辑:原始 URL 现已失效,但 Git Hub 上有一个工作镜像:
https ://raw.github.com/emacsmirror/dope/master/dope.el

于 2009-03-19T12:26:26.143 回答
5

严格来说,这不是您问题的答案,而是您可以使用该-q选项启动 emacs,将您的 .emacs 加载到缓冲区中并使用 Cx Ce 自己评估每个 sexpr ,而不是执行注释和重新启动的事情追查有问题的人。

于 2009-02-20T03:23:40.470 回答