我有3个ocaml模块,树的最后一个执行实际计算并使用另外2中定义的函数。
该计划的基本思想是将一个港口作为初始状态,其中包含船只,并移动这些船只,直到我们达到获胜的情况或不再有可能的移动。实际的代码在这里确实不是问题。它可能不是很有效,但找到了解决方案......除非它没有。
虽然程序在复杂情况下需要几秒钟,但在某些情况下,当我添加更多复杂性时,需要永远找到解决方案。
当我执行这样的程序时:
$ ocamlc -o test.exe port.ml moves.ml solver.ml
$ ./test.exe > file
生成的文件非常庞大,但是它的大小在一段时间后停止增加。在我看来,程序停止运行一段时间但没有终止,没有抛出Stackoverflow或内存不足错误。该程序根本不会继续执行。换句话说,命令
$ ./test.exe > file
仍然执行,但不再向该文件添加新行。如果我登录到shell本身而不是文件,我会得到相同的结果:一段时间后没有新的行继续添加。
这可能是什么?
主要功能(负责查找解决方案)使用Depth-First-Search算法,并包含许多List操作,例如List.fold,List.map,List.iter,List.partition,List.filter 。我当时认为这些函数可能在某些时刻处理大量复杂类型的问题,但同样,没有抛出错误,执行就停止了。
我非常模糊地解释了这一点,但我真的不明白这里的问题。我不知道问题是否与我的shell(Windows上的Ubuntu子系统)内存不足有关,或者ocaml List函数在某些时候受到限制......如果您有任何建议,请随时发表评论
要调试此类情况,您应该使用操作系统和OCaml基础结构本身提供的诊断实用程序。
首先,您将了解流程的状态。如果你正在运行Unix机器,你可以使用top
或htop
工具。否则,您可以使用任务管理器。
如果进程耗尽物理内存,则可以由操作系统进行交换。在这种情况下,所有内存操作都将变为硬盘读写。因此,收集存储在硬盘驱动器中的堆的垃圾将花费一些时间。如果是这种情况,那么您可以使用内存分析器来识别问题的关键。
如果该过程在不改变内存占用的情况下持续运行,那么您可能会遇到代码中的错误,即无限循环,或者您的某些算法具有指数级复杂性,正如Konstantin在评论。使用调试输出或跟踪来识别程序停止的位置。
最后,如果你的程序处于休眠状态,那么它可能是一个死锁。例如,如果您正在读取和写入同一文件,则最终可能会出现竞争情况。通常,如果您的程序是多线程的或运行多个进程,则有很多可能会导致竞争条件。