Ответ 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.