JAI创建似乎使文件描述符保持打开状态 [英] JAI create seems to leave file descriptors open

查看:106
本文介绍了JAI创建似乎使文件描述符保持打开状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些直到最近才可以使用的旧代码,但是现在看来已经讨厌了,因为它可以在使用OpenJDK 6而非Java SE 6的新服务器上运行.

I have some old code that was working until recently, but seems to barf now that it runs on a new server using OpenJDK 6 rather than Java SE 6.

问题似乎与JAI.create有关.我有jpeg文件,可以缩放并转换为png文件.这段代码曾经可以正常工作,但是现在已经转移到运行OpenJDK的盒子上了,文件描述符似乎永远都不会关闭,而且我看到越来越多的tmp文件堆积在服务器的tmp目录中.这些不是我创建的文件,因此我认为是由JAI完成的.

The problem seems to revolve around JAI.create. I have jpeg files which I scale and convert to png files. This code used to work with no leaks, but now that the move has been made to a box running OpenJDK, the file descriptors seem to never close, and I see more and more tmp files accumulate in the tmp directory on the server. These are not files I create, so I assume it is JAI that does it.

另一个原因可能是新服务器上的堆大小更大.如果JAI在完成时清理干净,但是GC发生的频率降低了,那么文件可能因此而堆积起来.减小堆大小不是一种选择,并且随着ulimit的增加,我们似乎遇到了不相关的问题.

Another reason might be the larger heap size on the new server. If JAI cleans up on finalize, but GC happens less frequently, then maybe the files pile up because of that. Reducing the heap size is not an option, and we seem to be having unrelated issues with increasing ulimit.

这是当我运行此文件时文件泄漏的示例:

Here's an example of a file that leaks when I run this:

/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-还有什么我需要研究的吗?

我现在不愿重提旧代码,但是如果没有其他选择...

I would rather not rewite the old code at this time, but if there is no other choice...

谢谢!

推荐答案

找到了!

因此,在代码的不同区域中,一个流被另一个流包裹:

So a stream gets wrapped by another stream in a different area in the code:

iis = ImageIO.createImageInputStream(stream);

再往下看,流被关闭.

使用Sun Java运行时,这似乎不会泄漏任何资源,但是使用Open JDK运行时,似乎会导致泄漏.

This doesn't seem to leak any resources when running with Sun Java, but does seem to cause a leak when running with Open JDK.

我不确定为什么会这样(尽管我有猜测,但我并未查看源代码进行验证),但这似乎正在发生.一旦我明确关闭包装流,一切就好了.

I'm not sure why that is (I have not looked at source code to verify, though I have my guesses), but that's what seems to be happening. Once I explicitly closed the wrapping stream, all was well.

这篇关于JAI创建似乎使文件描述符保持打开状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆