我制作了以下小程序来确定用于目标的内存是否在变得无法访问freeze(X,Goal)
时被回收:X
%:- use_module(library(freeze)). % Ciao Prolog needs this
freeze_many([],[]).
freeze_many([_|Xs],[V|Vs]) :-
freeze(V,throw(error(uninstantiation_error(V),big_freeze_test/3))),
freeze_many(Xs,Vs).
big_freeze_test(N0,N,Zs0) :-
( N0 > N
-> true
; freeze_many(Zs0,Zs1),
N1 is N0+1,
big_freeze_test(N1,N,Zs1)
).
让我们运行以下查询...
?- statistics, length(Zs,1000), big_freeze_test(1,500,Zs), statistics.
... 使用不同的 Prolog 处理器并查看内存消耗。 有什么不同!
(AMD64) SICStus Prolog 4.3.2:使用中的全局堆栈 = 108 MB (AMD64) B-Prolog 8.1:使用中的堆栈+堆 = 145 MB (i386) Ciao Prolog 1.14.2:使用中的全局堆栈 = 36 MB(~72 MB w/AMD64) (AMD64) SWI-Prolog 7.3.1:使用中的全局堆栈 = 0.5 MB (AMD64) YAProlog 6.2.2:使用中的全局堆栈 = 16 MB
当使用 运行更多迭代时?- length(Zs,1000), big_freeze_test(1,10000,Zs).
,我做了以下观察:
Ciao Prolog
{ERROR: Memory allocation failed [in Realloc()]}
在中止前报告。sicstus-prolog和b-prolog分配越来越多,直到机器死机。
- swi-prolog在3.554秒内执行所有迭代。
- yap也执行所有迭代,但需要36.910秒。
任何想法为什么它适用于 SWI-Prolog 和 YAProlog,但不适用于其他?
考虑到运行时间,为什么 SWI-Prolog 比 YAProlog 高出一个数量级以上?
我的直觉倾向于“属性变量”与“垃圾收集”的相互作用。SWI-Prolog 和 YAProlog 具有(共享?)与其他 Prolog 处理器不同的属性变量 API 和实现......而且,再一次,它可能是完全不同的东西。谢谢!