3.2 加载文件
在Scheme中使用load过程来加载文件。
load
filename [
environment [
syntax-table [
purify?]]] [procedure]
filename既可以是一个文件名字符串,也可以是多个文件的字符串列表。environment表示求值的环境,若没有给出环境,则使用当前的REPL环境。syntax-table已经不再使用,会被忽略掉。可选的purify?参数是一个布尔型值,指定是否在求值前把文件的内容转移到常空间。通过purify过程进行(见第3.4节[垃圾回收],P20)。
load会确定文件是二进制文件还是源代码文件,再做适当的操作。一般的,源代码文件带有scm扩展名(pathname type),二进制的SCode文件带有bin扩展名。本地代码二进制文件有com扩展名。(参见关于pathname-type的描述部分,见"MIT/GNU Scheme参考手册的"Pathnames的组成"一节"。)
load-noisily? [variable]
若此变量设置为"#t",load过程将打印文件中每个表达式求值时的值。否则,打印最后一条表达式的值。(注:此特性仅支持源代码文件。)
所有的路径名都是相对于工作目录的相对路径,Scheme启动时会对工作目录初始化。工作路径可以通过执行pwd过程或通过cd过程改变工作路径;参见Scheme参考手册的"工作目录"章节。文件也可以在Scheme第一次启动时加载,详见'--load'命令行选项。
load-option
symbol [
no-error?] [procedure]
加载选项设置,通过symbol传入;若已经加载了,则不做任何操作。若没有给定的选项,则会返回symbol并发出一个错误的信息。然而,若no-error?设置为true,则不会引发错误,但会返回#f。内置的加载选项如下:
compress 支持压缩和不压缩的文件。此选项没有文档;可以参考'runtime/cpress.scm'源文件。在运行时系统中对编译代码调试信息的压缩。
format 使用format过程。见Scheme参考手册的"格式化"章节。
gdbm 支持gdbm数据库的连接。未文档化;见源码文件"runtime/gdbm.scm"和"microcode/prgdbm.c"。
ordered-vector
支持对有序元素向量的搜索和完成(completion)。未文档化;见源文件"rumtime/ordvec.scm"。
rb-tree 红黑树数据类型。见Scheme参考手册中的"红黑树"章节。
regular-expression
支持正则表达式的字符串搜索和匹配。见Scheme参考手册的"正则表达式"章节。
stepper 支持Scheme表达式求值的单步调试。未文档化;见源文件"runtime/ystep.scm"。使用Edwin命令step-expression。
subprocess
支持在Scheme进程中启动其他程序作为子进程。未文档化;见源文件"runtime/process.scm"。在Edwin中大量使用。
synchronous-subprocess
支持同步运行子进程。见Scheme参考手册的"子进程"章节。
wt-tree 加权平衡树数据类型(weight-balanced tree)。见Scheme参考手册的"加权平衡树"章节。
除了内置的这些选项,你也可以通过修改库路径下的"optiondb.scm"文件定义其他选项用load-options指定加载。Scheme的发行版中附带了一个实例文件;通常这个文件包含了一系列对define-load-option过程的调用,通过如下表达式终止
(further-load-options standard-load-options)
define-load-option
symbol thunk . . . [procedure]
其中每一个thunk必须是一个没有参数的过程。定义名为symbol的加载选项。若load-option过程以symbol作为参数调用,则thunk的参数以从左向右的顺序执行。
3.3 世界图像(World Images)(或主标识)
一个世界图像,也叫做主标识(band),是一个包含哦完整Scheme系统的,可能有附加用户应用程序代码的文件。Scheme提供了一个保存和恢复世界图像的方法。这个方法可以写出一个文件,其中包含了运行进程中的所有Scheme代码和数据。由microcode加载的文件"runtime.com"就是这样一个主标识。可以使用disk-save过程制作你自己的主标识。
disk-save filename [identify] [procedure]
保存主标识到指定文件。可选参数identify控制当主标识恢复时的行为,如下:
not specified 启动顶层的REPL,以正常的方式辨识主标识。
a string 同样是启动顶层的REPL并以正常的方式辨识主标识,但在重启时会打印给出的字符串而不是"Scheme"。
the constant #t 重启时恢复到disk-save运行时的状态。当出现错误而不在顶层REPL但需要保存当前的状态时特别有用。
the constant #f 与#t类似,除了运行时系统不会运行正常的重启初始化;特别地,它不会加载你的初始化文件。
为了恢复保存的主标识,在启动Scheme时使用"--band"选项。或者可以对'(disk-restore filename)'求值,求值会破坏当前的世界(world),取而代之的是保存过的世界。disk-restore的参数可以略去,这样会取当前世界在上次恢复时使用的文件名。
3.4 垃圾回收
本节介绍控制垃圾回收的一些过程(procedure)。关s于Scheme如何使用内存的讨论见第2.3节[内存使用],P6。
gc-flip [
safety-margin] [procedure]
强制发生一次垃圾回收。返回在回收后的可用存储字数目,一个精确的非负整数。
safety-margin确定在监测到需要垃圾回收和在垃圾回收启动之前系统作业可以存储字的数目。(一个例子就是这样的一个系统作业改变run-light来显示"gc",当Scheme运行在Emacs上时。)一定要切记,不应该指定safety-margin,除非你知道你在做什么。若你指定的值太小,Scheme可能会变得不可用。
purify
object [
pure-space? [
queue?]] [procedure]
把object从堆转移到常空间。若object已经在常空间,则不操作。此转移会完整移动object;即使它是一个符合对象,如列表(list)、向量(vector)或记录(record),所有object指向的对象都会转移到常空间。
把对象转移到常空间有三个重要的效果。第一个也是最重要的一个就是对象将只占原来一半的空间,因为在堆上需要保留活动堆和不活动堆两部分空间;若对象在常空间中,不会被复制,则不会需要额外的空间。第二个效果就是垃圾回收会更少时,因为对象不再被复制。第三个效果就是分配给对象的空间将会永远保持,因为常空间不会被清理;任何在常空间的不可触对象都一直在那儿,知道Scheme进程被终止。
可选参数pure-space?已经过时了;默认一直是#t,指定时必须为#t。
可选参数queue?若为#f,则指定对象立即转移到常空间;否则对象将排队等待在下一次垃圾回收时再进入常空间。此参数默认为#t。请求排队的原因在于把对象转移到常空间需要进行一次垃圾回收,一个相对较慢的过程。通过对请求排队,就避免了这个开销,因为在垃圾回收时转移对象对垃圾回收的时间没有影响。此外,若多个请求在排队中,他们就可以在一次垃圾回收时进行处理,而分开做的话,每个转移都需要一次垃圾回收。
flush-purification-queue! [procedure]
强制进行任何挂起的转移队列请求。这个操作会检查转移队列,若有任何的请求,则强制一次垃圾回收进行对象转移。若队列为空,则不做任何操作。
print-gc-statistics [procedure]
打印内存分配和垃圾回收器的信息。信息会打印在当前的输出端口。显示正在使用的空间以及自由空间的数量,分开显示堆和常空间。数量以字为单位,并且按照1024字分块;块数字使得使用这些数字去调整堆(--heap)和常空间(--constant)的命令行选项的参数更加便利。在分配数字的后面紧跟着显示的是关于最近8次垃圾回收的信息,跟GC通知的格式一致。
注意调用print-gc-statistics过程时这些数字是精确的。对于堆来说,"in use"数字表示在上次垃圾回收后使用了多少内存,包括所有累积的活动对象以及未回收的垃圾。唯一精确确定活动存储大小的方法就是从堆大小减去“(gc-flip)”的值。堆大小可以通过print-gc-statistics"得到的in use"和"free"数字的相加得到。
(print-gc-statistics)
constant in use: 534121 words = 521 blocks + 617 words
constant free: 128 words = 0 blocks + 128 words
heap in use: 34845 words = 34 blocks + 29 words
heap free: 205530 words = 200 blocks + 730 words
GC #1: took: 0.13 (81%) CPU time, 0.15 (1%) real time; free: 207210
;No value
set-gc-notification! [on?] [procedure]
控制是否把垃圾回收的通知展示给用户。若on?为真,则启用;否则禁用。若on?没有给出,则默认值为#t。当Scheme启动时,通知被启用(修正:手册中写的是禁用)。
通知以但行显示如下,会显示已经发生的垃圾回收次数,运行垃圾回收的耗时以及垃圾回收后自由存储的数量。
GC #5: took: 0.50 (8%) CPU time, 0.70 (2%) real time; free: 364346
为了能舒心操作,垃圾回收后的自由存储的水昂应该占堆大小的一个实质性的比例。若CPU时间百分比一直较高(高于20%),你应该考虑运行在一个较大的堆上。一个可以减半GC开销的较粗的规则是把自由存储数量除以1000,再加上"--heap"命令行选项中使用的数值。不幸的是,没有办法不重启Scheme而调整堆的大小。
toggle-gc-notification! [procedure]
打开或关闭GC通知。若GC通知已经打开,则关闭;否则打开。