1.先看以下一段代码

import java.io.FileInputStream;

public class TTT {

public static void main(String[] args) throws Exception {

for (int i = 0; i < 10; i++) {

final String threadId = "thread_" + i;

Thread thread = new Thread(new Runnable() {

public void run() {

System.out.println(threadId + " started!");

try {

FileInputStream fis = new FileInputStream("/opt/test.log");

Thread.sleep(60 * 1000);

} catch (Exception ex) {

ex.printStackTrace();

}

System.out.println(threadId + " stopped!");

}

});

thread.start();

}

Thread.sleep(10 * 60 * 1000);

}

}

2.在linux上编译并运行这个类,然后使用linux的命令/usr/sbin/lsof -p 来查看这个程序打开的文件信息

$ /usr/sbin/lsof -p `ps -ef | grep java | grep TTT | awk '{print $2}'` | grep "test.log"

java 21562 fkong 3r REG 253,0 0 35471424 /opt/test.log

java 21562 fkong 4r REG 253,0 0 35471424 /opt/test.log

java 21562 fkong 5r REG 253,0 0 35471424 /opt/test.log

java 21562 fkong 6r REG 253,0 0 35471424 /opt/test.log

java 21562 fkong 7r REG 253,0 0 35471424 /opt/test.log

java 21562 fkong 8r REG 253,0 0 35471424 /opt/test.log

java 21562 fkong 9r REG 253,0 0 35471424 /opt/test.log

java 21562 fkong 10r REG 253,0 0 35471424 /opt/test.log

java 21562 fkong 11r REG 253,0 0 35471424 /opt/test.log

java 21562 fkong 12r REG 253,0 0 35471424 /opt/test.log

不管是在10个线程运行过程中还是运行完,使用lsof命令查看的结果都一样,都可以看到有10个文件流没有关闭。

3.下面我把这个代码做了一些改动,就是在线程执行完之后,将所有线程置为null,如下

import java.io.FileInputStream;

import java.util.ArrayList;

import java.util.List;

public class TTT {

public static void main(String[] args) throws Exception {

List threads = new ArrayList();

for (int i = 0; i < 10; i++) {

final String threadId = "thread_" + i;

Thread thread = new Thread(new Runnable() {

public void run() {

System.out.println(threadId + " started!");

try {

FileInputStream fis = new FileInputStream("/opt/test.log");

Thread.sleep(60 * 1000);

} catch (Exception ex) {

ex.printStackTrace();

}

System.out.println(threadId + " stopped!");

}

});

thread.start();

threads.add(thread);

}

Thread.sleep(2 * 60 * 1000);

for (Thread thread : threads) {

thread = null;

}

System.out.println("Clean up threads!");

Thread.sleep(10 * 60 * 1000);

}

}

再次在10个线程运行过程中和运行完毕后使用lsof查看,结果仍然类似,还是有10个文件流没有关闭。

我再次做了一些改动,在将所有线程置为null以后,增加(或者说是催促JVM)做几次gc操作,如下:

import java.io.FileInputStream;

import java.util.ArrayList;

import java.util.List;

public class TTT {

public static void main(String[] args) throws Exception {

List threads = new ArrayList();

for (int i = 0; i < 10; i++) {

final String threadId = "thread_" + i;

Thread thread = new Thread(new Runnable() {

public void run() {

System.out.println(threadId + " started!");

try {

FileInputStream fis = new FileInputStream("/opt/test.log");

Thread.sleep(60 * 1000);

} catch (Exception ex) {

ex.printStackTrace();

}

System.out.println(threadId + " stopped!");

}

});

thread.start();

threads.add(thread);

}

Thread.sleep(2 * 60 * 1000);

for (Thread thread : threads) {

thread = null;

}

System.out.println("Clean up threads!");

System.gc();

System.gc();

System.gc();

System.out.println("Finished GC!");

Thread.sleep(10 * 60 * 1000);

}

}

再次使用lsof查看,在运行中仍然还是可以看到那有10个文件流打开着,但是在“Finished GC!”之后,看到的结果是那10个打开的文件流都被关闭了。

最后,我干脆把那些设置thread为null的语句删除了,运行的结果也和上面执行gc操作的结果一致。

最终,JVM中对于那些打开了没有关闭的IO文件流,会在不再被使用的情况下,等到下次做Full GC的时候把他们全部回收,但是让JVM去干这些事总归还是不好的,还是那句老话,自己的事情自己做。

java 能不能回收 文件流_Java文件流关闭和垃圾回收机制相关推荐

  1. java 对象被回收的例子_Java对象的后事处理——垃圾回收(二)

    1 先谈Finalize() finalize()能做的所有工作,使用try-finally或者其他方式都可以做得更好.更及时,所以笔者建议大家完全可以忘掉Java语言中有这个方法的存在. --< ...

  2. JVM原理(Java代码编译和执行的整个过程+JVM内存管理及垃圾回收机制)

    转载注明出处: http://blog.csdn.net/cutesource/article/details/5904501 JVM工作原理和特点主要是指操作系统装入JVM是通过jdk中Java.e ...

  3. java文件与流_Java文件和流深入

    1.什么是数据流? 数据流是指所有的数据通信通道.有两类流,InputStream and OutputStream,Java中每一种流的基本功能依赖于它们.InputStream用于read,Out ...

  4. java io流过滤流_JAVA io流 文件流 字节流 字符流 过滤流 缓冲流

    一.概念 1.1.按流向分类: 输入流: 程序可以从中读取数据的流. 输出流: 程序能向其中写入数据的流. 1.2.按数据传输单位分类: 字节流:以字节(8位二进制)为单位进行处理.主要用于读写诸如图 ...

  5. java文件与流_Java文件与流

    文件 文件管理通过java.io包下.file类 作用: 1.文件属性 2.文件检查 3.文件删除 4.不包含对其文件内容的处理 File类的构造 语法: File f =new File(Strin ...

  6. JAVA mac系统io文件流_Java IO流基础1--IO的分类体系与文件流

    什么是IO流 Java中的IO 了解什么是IO流之前,要先知道什么是IO.IO,就是in和out(即输入和输出),指应用程序和外部设备之间的数据传递,常见的外部设备包括文件.管道.网络连接等. 流的概 ...

  7. java没有提供将字符流_JAVA字符流为什么没有把文件复制?

    源自:5-2 字符流之文件读写流 JAVA字符流为什么没有把文件复制? package IsPackage; import java.io.FileInputStream; import java.i ...

  8. java 文件转换成流_java -IO流_转换流

    转换流 在学习字符流(FileReader.FileWriter)的时候,其中说如果需要指定编码和缓冲区大小时,可以在字节流的基础上,构造一个InputStreamReader或者OutputStre ...

  9. java 删除文件失败_java 文件删除失败(被进程占用)

    解决方案:系统进行资源强制回收//System.gc();{不建议使用} 关闭流(未及时关闭会内存溢出) 问题--- 文件删除失败 (后来发现是被进程占用) 发现问题--第一次测试10个文件上传成功8 ...

  10. java绝对路径和相对路径_Java文件路径,绝对路径和规范路径

    java绝对路径和相对路径 Today we will look into the Java file path. Java File path can be abstract, absolute o ...

最新文章

  1. rust军用船指令_RUST物品指令清单(英文版)
  2. 【Python基础】弄懂这几个问题,拿下 Python 生成器!
  3. 【建议】如何优雅的提问?
  4. Emacs, Vi, Lisp, Logo, 小众语言集中营
  5. Java的@Serial批注
  6. 数仓架构的持续演进与发展 — 云原生、湖仓一体、离线实时一体、SaaS模式
  7. Cocoapods的Podfile常见语法总结
  8. C++ enum类型的一个更好的用法
  9. spark练习--统计xxx大学的各个少数名族的情况
  10. 达尔豪斯大学 计算机专业排名,加拿大留学计算机专业排名
  11. 总结数据库连接失败等问题
  12. 201621123062《java程序设计》第11周作业总结
  13. 【cqbzoj1526】 分梨子 乱搞(不是dp) 解题报告 c++
  14. 获取公众号的关注链接
  15. 安卓APP证书Android签名证书.keystore文件制作生成
  16. 植物识别小系统:“ 花草树木 皆有名“一热爱自然,从认识自然开始 ~
  17. html中给table添加行和删除行(等)
  18. 日记 [2007年08月29日]
  19. 点击pv转化率_点击转化率缩写
  20. 绿盟科技软件测试招聘,【绿盟科技软件测试面试】面试官很随和-看准网

热门文章

  1. php中添加访问器,php – 结合访问器和mutator逻辑,为模型添加自定义属性
  2. 那些伤害不大,侮辱性极强的瞬间
  3. Spring Boot 2.x基础教程:使用Redis的发布订阅功能
  4. 都2020 了,最流行的密码居然依旧是...
  5. 头条二面:宕机后,Redis如何实现快速恢复?
  6. 2020年最漂亮的Linux发行版
  7. python如何小写p转换p_Python进阶---python 中字符串大小写转换
  8. linix终端输入mysql,Linux服务器如何进入 MySQL 命令行
  9. C#机房重构-总结(二)
  10. ubuntu nano用法