IO流资源释放问题

时间:2021-03-14 05:02:18
一般使用完IO流之后都要通过close()来关闭,以释放系统资源。
例如以下代码中需要通过使用oos.close(),以释放资源
ObjectOutputStream oos  = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream("df.dat")));

如果使用后把引用变量设为null(如oos=null),是否IO流会被GC回收,之前就无需关闭了呢?

望Java高手解答,谢

14 个解决方案

#1


需要关闭,否则不会被CG回收

#2


该回复于2010-02-08 10:03:27被版主删除

#3


GC 回收是由系统调用的吧,至于何时回收就要看JVM了,除非你手动回收这个对象,否则由JVM干这个事情。当你吧oos 置null时 只是让指针计数器的值减一而已,但是不一定就是0了,所以也不一定会立马回收这个对象!

#4


设置为null会被GC回收,但是需要等到队列回收时才可以回收。
close是主动回收。直接回收掉。
没有其他选择,必然close

#5


引用 4 楼 xuetao121 的回复:
设置为null会被GC回收,但是需要等到队列回收时才可以回收。
 close是主动回收。直接回收掉。
 没有其他选择,必然close

按照我的理解,close只是关闭,并非回收,close以后对象还是存在的

#6


BufferedOutputStream
会被置为null。
但是外层的对象还在。
其实是一样的。
都不是上来就释放的。java没这个机制。java全部都是托管给GC程序的。

#7


IO流实例,除了内存资源(即该实例所占得内存)外,
还占用非内存资源(如文件句柄、socket句柄或其它)
close是释放 非内存的部分。
内存资源在java中由GC控制。

还记得 finalize 方法吗,
GC回收某个实例的内存资源前会先调用这个方法,以便做相关清理工作。
合理的假设,可认为IO流的实现会在 finalize 中检查是否释放了非内存资源,
没的话就在这里做,所以从大局来看不会有资源泄漏。
但会延迟非内存资源的释放,缺点可以想象得到。还是手动close最好。

#8


引用 7 楼 dengsf 的回复:
IO流实例,除了内存资源(即该实例所占得内存)外,
还占用非内存资源(如文件句柄、socket句柄或其它)
close是释放 非内存的部分。
内存资源在java中由GC控制。

还记得 finalize 方法吗,
GC回收某个实例的内存资源前会先调用这个方法,以便做相关清理工作。
合理的假设,可认为IO流的实现会在 finalize 中检查是否释放了非内存资源,
没的话就在这里做,所以从大局来看不会有资源泄漏。
但会延迟非内存资源的释放,缺点可以想象得到。还是手动close最好。

受教啦~!

#9


调用close时会调用flush,会把缓存写到文件中。我理解:一定要用close,否则缓存中的数据可能没有写到文件中。

#10


引用楼主 slmvpvip 的回复:
一般使用完IO流之后都要通过close()来关闭,以释放系统资源。
 例如以下代码中需要通过使用oos.close(),以释放资源
 ObjectOutputStream oos  = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream("df.dat")));

 如果使用后把引用变量设为null(如oos=null),是否IO流会被GC回收,之前就无需关闭了呢?

 望Java高手解答,谢


设为null后,在开一个流放到这个文件上,看能不能正常使用这个流。

#11


引用 9 楼 dong723232 的回复:
调用close时会调用flush,会把缓存写到文件中。我理解:一定要用close,否则缓存中的数据可能没有写到文件中。

close的确会自动调用flush ,不过即使不调用close也可以手动调用调用flush的

#12


引用 10 楼 zhangyou1010 的回复:
 设为null后,在开一个流放到这个文件上,看能不能正常使用这个流。


ObjectOutputStream oos;
while(true)
oos  = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream("df")));

这样的代码我试了试,貌似能一直跑……
原来我还以为会耗尽资源

#13


引用 7 楼 dengsf 的回复:
IO流实例,除了内存资源(即该实例所占得内存)外,
 还占用非内存资源(如文件句柄、socket句柄或其它)
 close是释放 非内存的部分。
 内存资源在java中由GC控制。

 还记得 finalize 方法吗,
 GC回收某个实例的内存资源前会先调用这个方法,以便做相关清理工作。
 合理的假设,可认为IO流的实现会在 finalize 中检查是否释放了非内存资源,
 没的话就在这里做,所以从大局来看不会有资源泄漏。
 但会延迟非内存资源的释放,缺点可以想象得到。还是手动close最好。

哦,貌似了解了。

就是说IO流在被GC回收的时候虽然效果同close一样,会释放非内存资源,不过这样可能会延迟非内存资源的释放,是这样吧

真是受教了


于是我想到,如果我把外层的IO流手动close了,包裹在里层的IO流也会同时自动被close吗?还是要等到外层被回收时里层才被close并被回收?

比如说我close了oos,那么里层的new BufferedOutputStream(new FileOutputStream("df.dat"))和new FileOutputStream("df.dat")也会同时被close吗?

#14


引用 13 楼 slmvpvip 的回复:
 于是我想到,如果我把外层的IO流手动close了,包裹在里层的IO流也会同时自动被close吗?还是要等到外层被回收时里层才被close并被回收?

 比如说我close了oos,那么里层的new BufferedOutputStream(new FileOutputStream("df.dat"))和new FileOutputStream("df.dat")也会同时被close吗?

会的。

#1


需要关闭,否则不会被CG回收

#2


该回复于2010-02-08 10:03:27被版主删除

#3


GC 回收是由系统调用的吧,至于何时回收就要看JVM了,除非你手动回收这个对象,否则由JVM干这个事情。当你吧oos 置null时 只是让指针计数器的值减一而已,但是不一定就是0了,所以也不一定会立马回收这个对象!

#4


设置为null会被GC回收,但是需要等到队列回收时才可以回收。
close是主动回收。直接回收掉。
没有其他选择,必然close

#5


引用 4 楼 xuetao121 的回复:
设置为null会被GC回收,但是需要等到队列回收时才可以回收。
 close是主动回收。直接回收掉。
 没有其他选择,必然close

按照我的理解,close只是关闭,并非回收,close以后对象还是存在的

#6


BufferedOutputStream
会被置为null。
但是外层的对象还在。
其实是一样的。
都不是上来就释放的。java没这个机制。java全部都是托管给GC程序的。

#7


IO流实例,除了内存资源(即该实例所占得内存)外,
还占用非内存资源(如文件句柄、socket句柄或其它)
close是释放 非内存的部分。
内存资源在java中由GC控制。

还记得 finalize 方法吗,
GC回收某个实例的内存资源前会先调用这个方法,以便做相关清理工作。
合理的假设,可认为IO流的实现会在 finalize 中检查是否释放了非内存资源,
没的话就在这里做,所以从大局来看不会有资源泄漏。
但会延迟非内存资源的释放,缺点可以想象得到。还是手动close最好。

#8


引用 7 楼 dengsf 的回复:
IO流实例,除了内存资源(即该实例所占得内存)外,
还占用非内存资源(如文件句柄、socket句柄或其它)
close是释放 非内存的部分。
内存资源在java中由GC控制。

还记得 finalize 方法吗,
GC回收某个实例的内存资源前会先调用这个方法,以便做相关清理工作。
合理的假设,可认为IO流的实现会在 finalize 中检查是否释放了非内存资源,
没的话就在这里做,所以从大局来看不会有资源泄漏。
但会延迟非内存资源的释放,缺点可以想象得到。还是手动close最好。

受教啦~!

#9


调用close时会调用flush,会把缓存写到文件中。我理解:一定要用close,否则缓存中的数据可能没有写到文件中。

#10


引用楼主 slmvpvip 的回复:
一般使用完IO流之后都要通过close()来关闭,以释放系统资源。
 例如以下代码中需要通过使用oos.close(),以释放资源
 ObjectOutputStream oos  = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream("df.dat")));

 如果使用后把引用变量设为null(如oos=null),是否IO流会被GC回收,之前就无需关闭了呢?

 望Java高手解答,谢


设为null后,在开一个流放到这个文件上,看能不能正常使用这个流。

#11


引用 9 楼 dong723232 的回复:
调用close时会调用flush,会把缓存写到文件中。我理解:一定要用close,否则缓存中的数据可能没有写到文件中。

close的确会自动调用flush ,不过即使不调用close也可以手动调用调用flush的

#12


引用 10 楼 zhangyou1010 的回复:
 设为null后,在开一个流放到这个文件上,看能不能正常使用这个流。


ObjectOutputStream oos;
while(true)
oos  = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream("df")));

这样的代码我试了试,貌似能一直跑……
原来我还以为会耗尽资源

#13


引用 7 楼 dengsf 的回复:
IO流实例,除了内存资源(即该实例所占得内存)外,
 还占用非内存资源(如文件句柄、socket句柄或其它)
 close是释放 非内存的部分。
 内存资源在java中由GC控制。

 还记得 finalize 方法吗,
 GC回收某个实例的内存资源前会先调用这个方法,以便做相关清理工作。
 合理的假设,可认为IO流的实现会在 finalize 中检查是否释放了非内存资源,
 没的话就在这里做,所以从大局来看不会有资源泄漏。
 但会延迟非内存资源的释放,缺点可以想象得到。还是手动close最好。

哦,貌似了解了。

就是说IO流在被GC回收的时候虽然效果同close一样,会释放非内存资源,不过这样可能会延迟非内存资源的释放,是这样吧

真是受教了


于是我想到,如果我把外层的IO流手动close了,包裹在里层的IO流也会同时自动被close吗?还是要等到外层被回收时里层才被close并被回收?

比如说我close了oos,那么里层的new BufferedOutputStream(new FileOutputStream("df.dat"))和new FileOutputStream("df.dat")也会同时被close吗?

#14


引用 13 楼 slmvpvip 的回复:
 于是我想到,如果我把外层的IO流手动close了,包裹在里层的IO流也会同时自动被close吗?还是要等到外层被回收时里层才被close并被回收?

 比如说我close了oos,那么里层的new BufferedOutputStream(new FileOutputStream("df.dat"))和new FileOutputStream("df.dat")也会同时被close吗?

会的。