ent*_*enr 2 java memory memory-management bufferedreader inputstreamreader
将InputStream作为来自某个地方,在那里将被进一步处理,然后关闭的参数传递。所以我不想在InputStream这里关闭。考虑以下代码:
void readInputStream(final InputStream inputStream) {
final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = bufferedReader.readLine() != null) {
// do my thing
}
}
Run Code Online (Sandbox Code Playgroud)
根据另一个Stackoverflow帖子,如果我关闭BufferedReaderand和/或the InputStreamReader,那么底层InputStream也将被关闭。
我的问题:即使底层InputStream在其他地方关闭,读者也需要关闭吗?如果不关闭阅读器,是否会发生内存泄漏?
读者是否需要关闭,即使底层
InputStream关闭了其他地方?
不,他们绝对不需要处于那种情况下。但无论如何,将它们关闭通常是一个好主意。
如果不关闭阅读器,是否会发生内存泄漏?
不,没有内存泄漏,前提是Reader一旦完成,内存本身就无法访问。此外,a Reader通常不会占用大量内存。
更为重要的问题是,如果不关闭,是否会导致资源泄漏Reader。答案是……这取决于。
如果你能保证底层InputStream总是会在应用程序中其他地方关闭,然后是采取的可能的内存泄漏的照顾。
如果不能保证,则存在资源泄漏的风险。底层操作系统级别的文件描述符是(例如)Linux中的有限资源。如果JVM无法关闭它们,它们可能会用完,并且某些系统调用将开始意外失败。
但是,如果您确实关闭,Reader则基础InputStream 将被关闭。
close()多次调用a InputStream是无害的,而且几乎不花任何费用。
唯一不应该关闭的情况Reader是关闭底层证券是错误的InputStream。例如,如果您关闭SocketInputStream其余的应用程序,则可能无法重新建立网络连接。同样,与InputStream关联的对象System.in通常无法重新打开。
在这种情况下,实际上可以安全地允许Reader您在方法中创建的对象进行垃圾回收。不同于InputStream,典型的Reader类不会重写Object::finalize()以关闭其数据源。
@Pshemo提出了有关系统设计的重点。
如果您接受an InputStream作为参数,那么用local Reader... 包裹它可能是错误的,尤其是a BufferedReader。A BufferedReader可能会在流中预读。如果在您的方法返回后该流将由调用方使用,则任何已读入缓冲区但未被该方法使用的数据都可能会丢失。
更好的主意是让呼叫者传递一个Reader。另外,此方法应记录为取得所有权的InputStream。在这种情况下,应该始终close()如此。