我有一些旧代码直到最近才可以使用,但现在它运行在使用 OpenJDK 6 而不是 Java SE 6 的新服务器上似乎很糟糕。
问题似乎围绕着 JAI.create。我有 jpeg 文件,我可以缩放并转换为 png 文件。这段代码过去可以正常工作,但现在已经转移到运行 OpenJDK 的机器上,文件描述符似乎永远不会关闭,而且我看到越来越多的 tmp 文件堆积在服务器上的 tmp 目录中。这些不是我创建的文件,所以我认为是 JAI 做的。
另一个原因可能是新服务器上的堆大小较大。如果 JAI 在 finalize 时进行了清理,但 GC 发生的频率较低,那么文件可能因此而堆积起来。减小堆大小不是一种选择,而且我们似乎遇到了与增加 ulimit 无关的问题。
这是我运行此文件时泄漏的文件示例:
/tmp/imageio7201901174018490724.tmp
一些代码:
// Processor is an internal class that aggregates operations
// performed on the image, like resizing
private byte[] processImage(Processor processor, InputStream stream) {
byte[] bytes = null;
SeekableStream s = null;
try {
// Read the file from the stream
s = SeekableStream.wrapInputStream(stream, true);
RenderedImage image = JAI.create("stream", s);
BufferedImage img = PlanarImage.wrapRenderedImage(image).getAsBufferedImage();
// Process image
if (processor != null) {
image = processor.process(img);
}
// Convert to bytes
bytes = convertToPngBytes(image);
} catch (Exception e){
// error handling
} finally {
// Clean up streams
IOUtils.closeQuietly(stream);
IOUtils.closeQuietly(s);
}
return bytes;
}
private static byte[] convertToPngBytes(RenderedImage image) throws IOException {
ByteArrayOutputStream out = null;
byte[] bytes = null;
try {
out = new ByteArrayOutputStream();
ImageIO.write(image, "png", out);
bytes = out.toByteArray();
} finally {
IOUtils.closeQuietly(out);
}
return bytes;
}
我的问题是:
- 有没有人遇到这个并解决了它?由于创建的 tmp 文件不是我的,我不知道它们的名称是什么,因此无法对它们做任何事情。
- 有哪些选择用于调整图像大小和重新格式化图像的库?我听说过 Scalr - 还有什么我应该研究的吗?
我宁愿此时不重写旧代码,但如果没有其他选择......
谢谢!