1

以下来自 top 命令:

                            size  res 
1127 ***       1  20    0   117M  2196K ttyin   0   0:00  0.00% gprolog

1149 ***       1  23    0 10700K  3728K ttyin   0   0:00  0.00% swipl

它的 RES 是合理的,但它的大小与 swipl 相比太大了。

操作系统是freebsd 9.0。

真挚地!

4

2 回答 2

5

在您的 ps/top-listing 中有两个数字:分配的虚拟内存(大小)和实际使用的物理内存(res)。由此看来,GNU Prolog 最初使用的内存比 SWI 少。即:GNU 为 2196K,SWI 为 3728K。

但是你不能仅从这些数字得出任何相关的结论。您唯一可以说的是,具有顶层的默认环境需要大量内存才能启动 - 前提是您没有使用另一个程序“分页”进程......

两个系统都试图将内存消耗保持在较低水平,但水平不同:

GNU Prolog为跳过未使用的内置谓词的独立可执行文件提供编译。可执行代码的处理方式与 C 类似:因此它以只读方式映射到物理内存中。如果您运行此类可执行文件的多个实例,它们都将为可执行文件共享相同的物理内存。

不利的一面是,GNU Prolog 缺乏垃圾收集。对于堆(copystack)和原子(可符号化)。为了避免溢出处理,内存区域被大量分配。但这只是对虚拟内存的保留。据我所知,所有当前的 Unix 变体都会过度使用虚拟内存,因此这不会占用相应的交换空间。

另一方面,SWI-Prolog将其 Prolog 代码分配在可写内存中。此外,在 GC 期间内存被“触及”(标记/未标记)。因此,Prolog 程序不能在不同的 SWI 实例之间共享,即使像 mergemem 这样的动态重新共享也不行。也就是说,mergemem(或类似的)可以页面共享它,但在下一次 db-GC 时,它是写时复制不共享的。请参阅链接如何共享可以减少 SICStus 的内存消耗。但是 SWI 具有多线程支持,这在一定程度上促进了共享。

SWI 拥有最好和最完整的堆和原子垃圾收集器之一。

因此,您的里程可能会有所不同。毫无疑问,最好的系统将结合两者的优点。

于 2013-01-10T11:11:22.910 回答
4

gprolog映射所有堆栈(其大小通过环境变量控制)。默认值为16MB for the trail,约束和本地堆栈+ 32MB for the heap。还有原子表(也通过环境变量控制)。在大多数情况下,默认值很高。注意:由于这是虚拟内存(通过 mmap),因此仅在需要时才进行物理分配。所以分配大量内存并不是真正的问题(但是交换应该足以满足最大所需的内存)。无论如何,您可以重新定义它们(例如,如果您不使用 FD 求解器,您可以将 CSTRSZ env var 设置为 0)。

SWI Prolog 在需要时动态地增加(并且我想减少)其内部堆栈的大小。所以在开始时需要很少的内存。

于 2013-01-10T08:46:04.943 回答