以下是来自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。
此致!
答案 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在需要时动态增加(并且我认为减少)其内部堆栈的大小。因此,一开始只需要很少的内存。