程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Java文件流封閉和渣滓收受接管機制

Java文件流封閉和渣滓收受接管機制

編輯:關於JAVA

Java文件流封閉和渣滓收受接管機制。本站提示廣大學習愛好者:(Java文件流封閉和渣滓收受接管機制)文章只能為提供參考,不一定能成為您想要的結果。以下是Java文件流封閉和渣滓收受接管機制正文


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 <pid>來檢查這個法式翻開的文件信息

$ /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<Thread> threads = new ArrayList<Thread>();
		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<Thread> threads = new ArrayList<Thread>();
		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去干這些事總清償是欠好的,照樣那句老話,本身的工作本身做。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved