为什么gprolog需要这么多内存?

时间:2013-01-10 01:36:48

标签: prolog gnu-prolog

以下是来自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。

此致!

2 个答案:

答案 0 :(得分:5)

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

但是你不能单独从这些数字中得出任何相关的东西。你唯一可以说的是,带有顶层的默认环境需要很多内存才能启动 - 只要你没有"页面输出"与另一个程序的过程......

两个系统都试图将内存消耗降低,但是在不同的级别上:

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

缺点是,GNU Prolog缺乏垃圾收集。堆(copystack)和原子(symboltable)都有。为了避免溢出处理,内存区域被大量分配。但这只是对虚拟内存的预留。据我所知,目前所有的Unix变种都过度提交了虚拟内存,所以这并没有带走相应的交换空间。

另一方面,

SWI-Prolog在可写内存中分配其Prolog代码。此外,记忆被触及" GC期间(标记/未标记)。因此,Prolog程序不能在不同的SWI实例之间共享,甚至不能与dynamic re-sharing like mergemem共享。也就是说,mergemem(或类似的)可以页面共享它,但是在下一个db-GC上,它是copy-on-write unshared。请参阅链接共享如何减少SICStus的内存消耗。但是,SWI具有多线程支持,这在一定程度上会导致共享。

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

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

答案 1 :(得分:4)

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

SWI Prolog在需要时动态增加(并且我认为减少)其内部堆栈的大小。因此,一开始只需要很少的内存。