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。
该函数会在纯净存储中为 object 创建一份副本并返回。 复制字符串时,它会直接在纯净存储中新建内容相同但不包含文本属性的字符串。 它会递归复制向量与 cons 单元的内容。 对于符号等其他对象则不创建副本,仅原样返回。 若尝试复制标记对象,该函数会抛出错误。
该函数仅在 Emacs 构建与转储期间生效,其余时刻为空操作; 通常仅在预加载 Lisp 文件中调用。
该变量的值为当前已分配的纯净存储字节数。 通常在转储后的 Emacs 中,该数值会非常接近可用纯净存储总量—— 若非如此,我们会减少预分配空间。
该变量决定 defun 是否将函数定义复制到纯净存储中。
若其值非 nil,函数定义会被复制到纯净存储。
在初始加载构建 Emacs 的所有基础函数时,该标记为 t
(使这些函数可共享且不被回收)。
将 Emacs 转储为可执行文件时,无论转储前后该变量实际取值如何,
都会被写入 nil。
请勿在运行中的 Emacs 内修改该标记。