gpt4 book ai didi

java - JAI create 似乎让文件描述符保持打开状态

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:16:59 26 4
gpt4 key购买 nike

我有一些直到最近才有效的旧代码,但现在似乎厌恶它在使用 OpenJDK 6 而不是 Java SE 6 的新服务器上运行。

问题似乎与 JAI.create 有关。我有 jpeg 文件,我缩放并转换为 png 文件。这段代码过去没有泄漏,但现在已经转移到运行 OpenJDK 的机器上,文件描述符似乎永远不会关闭,而且我看到越来越多的 tmp 文件累积在服务器上的 tmp 目录中。这些不是我创建的文件,所以我假设是 JAI 做的。

另一个原因可能是新服务器上的堆大小更大。如果 JAI 在完成时清理,但 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;
}

我的问题是:

  1. 有没有人遇到并解决了这个问题?由于创建的 tmp 文件不是我的,我不知道它们的名称,因此无法对它们做任何事情。
  2. 可以选择哪些库来调整图像大小和重新格式化图像?我听说过 Scalr - 还有什么我应该研究的吗?

此时我宁愿不重写旧代码,但如果没有其他选择...

谢谢!

最佳答案

只是对临时文件/终结器问题的评论,现在您似乎已经解决了问题的根源(评论太长了,所以我将其作为答案发布...:-P):

临时文件由 ImageIO 的 FileCacheImageInputStream 创建。每当您调用 ImageIO.createImageInputStream(stream)useCache 时都会创建这些实例。标志为 true(默认值)。您可以将其设置为 false 以禁用磁盘缓存,但会牺牲内存中的缓存。当您有一个大堆时,这可能有意义,但如果您正在处理非常大的图像,则可能没有意义。

我还认为您(几乎)对终结器问题是正确的。您会在 FileCacheImageInputStream (Sun JDK 6/1.6.0_26) 上找到以下“finalize”方法:

protected void finalize() throws Throwable {
// Empty finalizer: for performance reasons we instead use the
// Disposer mechanism for ensuring that the underlying
// RandomAccessFile is closed/deleted prior to garbage collection
}

类的构造函数中有一些非常“有趣”的代码,它们设置了在实例结束时自动关闭和处理流(如果客户端代码忘记这样做)。这在 OpenJDK 实现中可能有所不同,至少看起来有点老套。目前我也不清楚我们在谈论什么“性能原因”......

在任何情况下,似乎在 ImageInputStream 实例上调用 close,就像您现在所做的那样,将正确关闭文件描述符并删除临时文件。

关于java - JAI create 似乎让文件描述符保持打开状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18517463/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com