Do unclosed streams cause memory leaks in java?

前端 未结 3 1735
忘了有多久
忘了有多久 2020-12-03 05:35

I believe open streams cause memory leak in java (at least java 1.6 and earlier did had this problem).

But, while searching (even here), I found some people agreein

3条回答
  •  一个人的身影
    2020-12-03 05:55

    (at least java 1.6 and earlier did had this problem).

    ANY version of Java, and for that matter, ANY language, has this problem; it is not specific to Java.

    If you get hold of an input or output handle which needs system resources, you need to release them no matter what.

    Java has Closeable to signify that the instance you hold may, or may not, hold system resources; but in the event that it does, if you don't .close() it you'll leak resources; it's that simple.

    For instance, you may have a method which has an InputStream as an argument; OK, fine, but what is this InputStream? Is it a FileInputStream or a ByteArrayInputStream, or even something else? You cannot know. The first needs to be closed properly but the second doesn't need to.

    So what? .close() them all anyway, you have nothing to lose. Do you really want to take the chance?

    With Java 6, you'll want to use Guava's Closer, since this is the safest way to have all your resources closed (and the JDK does not provide such a tool):

    final Closer closer = Closer.create();
    
    try {
        final InputStream in = closer.register(openInHere());
        final InputStream in2 = closer.register(...);
        final OutputStream out = closer.register(...);
        // do work with in, in2, out, other
    } catch (WhateverException e) {
        // IF WhateverException is not an IOException and you want to rethrow...
        // throw closer.rethrow(e, WhateverException.class);
    } finally {
        closer.close(); // always safe
    }
    

    With Java 7, you have try-with-resources which works with all AutoCloseable resources (which Closeable extends):

    try (
        final InputStream in = ...;
        // etc
    ) {
        // work with AutoCloseable resources
    } catch (WhateverException e) {
        // deal with e, rethrow if necessary
    }
    

    The main difference between Closer and try-with-resources is that with the latter, resources will be closed before catch whereas Closer will close them in finally.

    But again: don't take a chance. Close them all.

提交回复
热议问题