E.2 纯净存储

Emacs Lisp 为用户创建的 Lisp 对象使用两种存储: 普通存储(normal storage)纯净存储(pure storage)。普通存储用于保存 Emacs 会话期间创建的所有新数据 (see 垃圾回收)。纯净存储用于预加载标准 Lisp 文件中的 特定数据—这些数据在 Emacs 实际运行过程中不应发生改变。

纯净存储仅在 temacs 加载标准预加载 Lisp 库时进行分配。 在 emacs 文件中,它会被标记为只读(在支持该特性的操作系统上), 从而使该内存空间可被同一台机器上同时运行的所有 Emacs 进程共享。 纯净存储不可扩展;Emacs 编译时会分配固定大小的空间, 如果该空间不足以容纳预加载库,temacs 会为超出部分 分配动态内存。如果 Emacs 使用 pdump 方式转储 (see 构建 Emacs),纯净空间溢出并无特殊影响 (仅表示部分预加载内容无法与其他 Emacs 进程共享)。 但如果使用现已废弃的 unexec 方式转储,生成的镜像虽可运行, 垃圾回收 (see 垃圾回收) 会在此情况下被禁用,从而造成内存泄漏。 除非你尝试预加载额外库或为标准库添加功能,否则通常不会出现此类溢出。 若 Emacs 由 unexec 转储生成,启动时会显示关于溢出的警告。 出现该情况时,你应增大文件 src/puresize.h 中的编译参数 SYSTEM_PURESIZE_EXTRA 并重新编译 Emacs。

Function: purecopy object

该函数会在纯净存储中为 object 创建一份副本并返回。 复制字符串时,它会直接在纯净存储中新建内容相同但不包含文本属性的字符串。 它会递归复制向量与 cons 单元的内容。 对于符号等其他对象则不创建副本,仅原样返回。 若尝试复制标记对象,该函数会抛出错误。

该函数仅在 Emacs 构建与转储期间生效,其余时刻为空操作; 通常仅在预加载 Lisp 文件中调用。

Variable: pure-bytes-used

该变量的值为当前已分配的纯净存储字节数。 通常在转储后的 Emacs 中,该数值会非常接近可用纯净存储总量—— 若非如此,我们会减少预分配空间。

Variable: purify-flag

该变量决定 defun 是否将函数定义复制到纯净存储中。 若其值非 nil,函数定义会被复制到纯净存储。

在初始加载构建 Emacs 的所有基础函数时,该标记为 t (使这些函数可共享且不被回收)。 将 Emacs 转储为可执行文件时,无论转储前后该变量实际取值如何, 都会被写入 nil

请勿在运行中的 Emacs 内修改该标记。