Linux ImageMagick转换内存不足

Linux ImageMagick转换内存不足,linux,imagemagick,out-of-memory,Linux,Imagemagick,Out Of Memory,我有一个自定义应用程序在CentOS 6.7上运行,内存为64 GB,它基本上是一个文件爬虫,每次发现与某些文件扩展名(主要是TIFF或多页TIFF)匹配的文件时,都会调用下面的bash脚本。 我不能确切地说出被考虑的频率和文件数量,但它的数量是数千 #!/bin/bash IMAGE_INPUT=$1 OUTPUT=$2 TMP_FOLDER=/data/tesseract-tmp # generating a unique random file name TFN=`cat /dev/u

我有一个自定义应用程序在CentOS 6.7上运行,内存为64 GB,它基本上是一个文件爬虫,每次发现与某些文件扩展名(主要是TIFF或多页TIFF)匹配的文件时,都会调用下面的bash脚本。 我不能确切地说出被考虑的频率和文件数量,但它的数量是数千

#!/bin/bash

IMAGE_INPUT=$1
OUTPUT=$2
TMP_FOLDER=/data/tesseract-tmp

# generating a unique random file name
TFN=`cat /dev/urandom | tr -cd 'a-f0-9' | head -c 32`;
# converting the image and putting the result into the TFN
/usr/bin/convert -density 288 "$IMAGE_INPUT" -resize 75% -quality 100 -append jpeg:$TMP_FOLDER/$TFN;
# extract text with tesseract and put it into a result file
/usr/local/bin/tesseract $TMP_FOLDER/$TFN $TMP_FOLDER/$TFN.out;
cp $TMP_FOLDER/$TFN.out.txt $OUTPUT;
# returning the file content to std output
cat $OUTPUT;
临时文件正在由cronjob清理

我注意到,经过一段时间和对脚本的大量调用,top命令显示imagemagick的gsconvert进程占用了所有可用内存,并开始消耗所有可用的交换空间。 如果我不杀死这些进程,系统就会耗尽内存并冻结

我怎样才能解决这个问题? 是否有办法限制特定程序(convert)的内存量,或者是否有可能将脚本调用的执行排队

注意:我已经看到convert命令有limit选项,但如果我理解正确,它适用于运行进程的单个实例,而我希望限制整个运行实例的内存使用


谢谢

您可以尝试使用GNU Parallel来限制内存使用,并通过并行运行作业来提高速度。基本上,在指定的内存可用之前,它不会启动另一个并行作业

因此,假设您的脚本名为
OCR
,并将输入文件名作为参数:

parallel --memfree 1G OCR {} ::: *.tif

您可以尝试使用gnupallel来限制内存使用,并通过并行运行作业来提高速度。基本上,在指定的内存可用之前,它不会启动另一个并行作业

因此,假设您的脚本名为
OCR
,并将输入文件名作为参数:

parallel --memfree 1G OCR {} ::: *.tif

我已使用以下命令解决了此问题:

nice -20 /usr/bin/convert -limit memory 32 -limit map 32 -density 288 "$IMAGE_INPUT" -resize 75% -quality 100 -append jpeg:$TMP_FOLDER/$TFN;
这样,内存就被完全占用了,但它永远不会开始交换,系统也永远不会冻结


无论如何,感谢Mark Setchell answer,它对我的目的非常有用和合适。

我使用以下命令解决了它:

nice -20 /usr/bin/convert -limit memory 32 -limit map 32 -density 288 "$IMAGE_INPUT" -resize 75% -quality 100 -append jpeg:$TMP_FOLDER/$TFN;
这样,内存就被完全占用了,但它永远不会开始交换,系统也永远不会冻结


无论如何,感谢Mark Setchell的回答,它对我的目的非常有用和合适。

»…在多次调用脚本之后…«?每次调用脚本后,您是否都尝试过清理?也许有些进程(gs和convert)会继续运行,不再需要了,所以用
kill
killall
杀死它们应该没有问题。我会用kill试试,因为我不能杀死所有进程,因为我最终也会杀死其他仍在运行的进程……这里
-append
做什么?为什么不使用
tmpnam
生成临时文件?为什么不在完成后删除临时文件,以免文件系统中出现垃圾文件?嗨,标记,追加是因为输入可能是多页tiff。不知道tmpnam,但它是否应该改变这种情况?临时文件被cronjob删除了。很好地更新了你的Q,但是事情仍然很模糊。那么可以同时运行多个
myScript
?你需要量化这些东西。为什么不添加一个
echo“在$(日期)开始处理$文件”>$logFile;myScript;echo“在$(日期)>$logFile完成处理$文件”
包装
myScript
。您还可以执行
(echo$(date);while((i++>100));do ps-ef | grep-E'gs | convert';sleep 1;echo$(date))>processesInfo.txt
(或类似操作),以查看有多少同时运行。祝你好运。»…在多次调用脚本之后…«?每次调用脚本后,您是否都尝试过清理?也许有些进程(gs和convert)会继续运行,不再需要了,所以用
kill
killall
杀死它们应该没有问题。我会用kill试试,因为我不能杀死所有进程,因为我最终也会杀死其他仍在运行的进程……这里
-append
做什么?为什么不使用
tmpnam
生成临时文件?为什么不在完成后删除临时文件,以免文件系统中出现垃圾文件?嗨,标记,追加是因为输入可能是多页tiff。不知道tmpnam,但它是否应该改变这种情况?临时文件被cronjob删除了。很好地更新了你的Q,但是事情仍然很模糊。那么可以同时运行多个
myScript
?你需要量化这些东西。为什么不添加一个
echo“在$(日期)开始处理$文件”>$logFile;myScript;echo“在$(日期)>$logFile完成处理$文件”
包装
myScript
。您还可以执行
(echo$(date);while((i++>100));do ps-ef | grep-E'gs | convert';sleep 1;echo$(date))>processesInfo.txt
(或类似操作),以查看有多少同时运行。祝你好运