Подтвердить что ты не робот

Должен ли Class.getResourceAsStream быть закрыт?

Мне было интересно, требуется ли это, поскольку, когда я использую этот метод, файл читается из пути к классам. "Не закрывает" это приводит к утечке памяти.

Как я могу проверить такие утечки памяти?

4b9b3361

Ответ 1

Вы предполагаете, что Class.getResourceAsStream() всегда будет возвращать поток, который указывает на файл внутри JAR файла вашего класса. Это неверно Ваш classpath может также содержать папки, и в этом случае Class.getResourceAsStream() вернет FileInputStream. Некоторые другие загрузчики классов могут также возвращать ресурсы другого типа, такие как удаленные файлы (в случае URLClassLoader).

Даже в случае файла JAR, возможно, что реализация поддерживает каким бы то ни было образом постоянное представление внутри файла JAR сжатых байтов файла, к которому вы обращаетесь. Возможно это держит на памяти отображенный ByteBuffer...

Зачем рисковать? Вы должны всегда закрывать потоки (и любые другие Closeable, на самом деле), независимо от того, как они были переданы вам.

Обратите внимание, что начиная с Java 8 предпочтительным методом для обработки любого ресурса является конструкция try-with-resources. Он правильно обрабатывает несколько угловых случаев, которыми очень трудно управлять в написанном от руки коде, и все же написать его почти так же легко, как если бы вы просто забыли о закрытии ресурса. Например, вы можете использовать такой код:

    try (InputStream in = Class.getResourceAsStream("someresource.txt")) {
        // Use the stream as you need to...
    }

    // Then forget about it... and yet, it has been closed properly.

Что касается обнаружения утечек, лучшая стратегия - получить дамп памяти во время выключения виртуальной машины, а затем проанализировать его с помощью какого-либо инструмента. Два популярных инструмента - это jhat и Eclipse mat.

Ответ 2

Как правило, вы должны закрыть все потоки (и другие типы, которые обеспечивают близкую функциональность). Это может привести к утечке ресурсов ro (память - это один тип ресурса).

Хотя существует автоматическая сборка мусора, которая в конечном итоге восстанавливает память, когда объект больше не упоминается, он может по-прежнему содержать собственные ресурсы, которые могут быть недоступны. Кроме того, если какой-либо другой долгоживущий объект (например, загрузчик классов) удерживает ресурс, он не будет востребован сборщиком мусора.

Если ваша программа недолговечна, или вы только открываете небольшое количество ресурсов, вы можете не столкнуться с проблемами, но утечки ресурсов трудно обнаружить в долгосрочных приложениях.

Ответ 3

Возвращаемый тип является входным потоком, поэтому, независимо от конкретной реализации (которая может меняться от версии к версии), у вас есть метод close(), который следует вызывать imho.

Независимо от того, действительно ли этот метод делает что-то полезное с текущей версией.