我正在使用NLP库(Stanford NER),它会为罕见的输入文档抛出OOM错误。
我计划最终隔离这些文件,并弄清楚它们会导致错误,但这很难做到(我在Hadoop中运行,所以我只知道错误发生在17%通过拆分379/500或其他什么像那样)。作为临时解决方案,我希望能够对此特定呼叫应用CPU和内存限制。
我不确定最好的办法是什么。我的第一个是创建一个线程的固定线程池,并在Future上使用timed get()。这至少会给我一个挂钟限制,这可能会有所帮助。
我的问题是,是否有任何方法可以通过合理的努力做得更好。
答案 0 :(得分:2)
我不熟悉Hadoop,但是不要忘记你的JVM会有一个隐含的高端内存边界(如果我的内存是正确的话,服务器为64Mb)。我会检查你的JVM运行的内存配置(选项here)
您可以通过指定内存上限来覆盖它:
java -Xmx512m
到(比方说)将限制设置为512Mb。
设置CPU分配超出了JVM的范围,并且将是特定于操作系统的机制(如果你可以完成的话)
如果您从JVM并行调度这些作业,那么运行单线程(或有限线程)线程池可能会对您有所帮助。但是(再次)这取决于您的实现,需要更多详细信息。
答案 1 :(得分:1)
只需捕获OutOfMemoryError,记录您所在的文档,然后转到下一个文档。垃圾收集器将确保您有足够的内存用于下一个文档。
(这是我使用斯坦福依赖解析器进行下一句话的策略之一,如果一个句子太长或者有问题需要解析。)
答案 2 :(得分:0)
如果您要做的就是弄清楚哪些文档崩溃了,您应该将调用记录到NLP库,“即将映射文档x”。当您看到OOM时,映射器的日志将包含厄运文档。就像你说的那样,你应该确定该文档的哪些特征导致库崩溃。
根据我的经验,特别是如果文档是由互联网上的人创建的,你会在某处发现一些疯狂的巨大文档。那时你必须决定如何处理这些文件;要么忽略它们,要么截断它们。