1. انظر أولاً إلى الكود التالي
استيراد java.io.fileInputStream ؛ الفئة العامة ttt {public static void main (string [] args) يلقي الاستثناء {for (int i = 0 ؛ i <10 ؛ i ++) {final string threadid = "thread_" + i ؛ thread = new thread (new runnable () {public void run () {system.Out. = جديد fileInputStream ("/opt/test.log") ؛ thread.sleep (60 * 1000) ؛} catch (استثناء ex) {ex.printstacktrace () ؛} system.out.println (threadid + "stopped!") ؛}})2. تجميع وتشغيل هذه الفئة على Linux ، ثم استخدم الأمر Linux/usr/sbin/lsof -p <pid> لعرض معلومات الملف التي فتحها هذا البرنامج.
$/usr/sbin/lsof -p `ps -ef | جريب جافا | GREP TTT | awk '{print $ 2}' `| grep "test.log" java 21562 fkong 3r reg 253،0 0 35471424 /opt/test.logjava 21562 fkong 4r reg 253،0 0 35471424 /opt/test.logjava 21562 fkong 5r Reg 253،0 0 35471424. 21562 fkong 6r Reg 253،0 0 35471424 /opt/test.logjava 21562 fkong 7r Reg 253،0 0 35471424 /opt/test.logjava 21562 fkong 8r Reg 253،0 0 35471424 253،0 0 35471424 /opt/test.logjava 21562 fkong 11r Reg 253،0 0 35471424 /opt/test.logjava 21562 fkong 11r Reg 253،0 0 35471424 /opt/test.logjava /opt/test.logسواء كان ذلك أثناء تشغيل أو بعد 10 مؤشرات ترابط ، فإن نتائج المشاهدة باستخدام أمر LSOF هي نفسها. يمكنك أن ترى أن 10 تدفقات ملفات غير مغلقة.
3. لقد قمت بإجراء بعض التغييرات على هذا الرمز أدناه ، أي بعد تنفيذ مؤشر الترابط ، يتم تعيين جميع مؤشرات الترابط على NULL ، على النحو التالي
استيراد java.io.fileInputStream ؛ استيراد java.util.arraylist ؛ استيراد java.util.list ؛ الفئة العامة ttt {public static void main (string [] args) rems stispion {finate threads = threads = new arraylist <shind> () ؛ RunNable () {public void run () {system.out.println (threadid + "legt!") ؛ حاول {fileInputStream fis = new FileInputStream ("/opt/test.log") ؛ thread.sleep (60 * 1000) ؛ "توقف!") ؛}}) ؛ thread.start () ؛ threads.add (موضوع) ؛ مرة أخرى ، استخدم LSOF لعرضه أثناء وبعد تشغيل المواضيع العشرة ، وما زالت النتائج متشابهة ، ولا تزال هناك 10 تدفقات ملفات غير مغلقة.
لقد قمت ببعض التغييرات مرة أخرى ، بعد تعيين جميع مؤشرات الترابط على NULL ، إضافة (أو حث JVM) للقيام ببعض عمليات GC ، على النحو التالي:
استيراد java.io.fileInputStream ؛ استيراد java.util.arraylist ؛ استيراد java.util.list ؛ الفئة العامة ttt {public static void main (string [] args) rems stispion {finate threads = threads = new arraylist <shind> () ؛ RunNable () {public void run () {system.out.println (threadid + "legt!") ؛ حاول {fileInputStream fis = new FileInputStream ("/opt/test.log") ؛ thread.sleep (60 * 1000) ؛ "توقف!") ؛}}) ؛ thread.start () ؛ threads.add (موضوع) ؛ GC! ") ؛ thread.sleep (10 * 60 * 1000) ؛}}استخدم LSOF للعرض مرة أخرى ، ولا يزال بإمكانك معرفة أن 10 تدفقات ملفات مفتوحة أثناء التشغيل ، ولكن بعد "GC!" ، فإن النتيجة هي أن تدفقات الملفات 10 مغلقة.
أخيرًا ، قمت ببساطة بحذف العبارات التي تحدد مؤشر الترابط على NULL ، ونتائج التشغيل تتفق أيضًا مع نتائج أداء عمليات GC أعلاه.
في النهاية ، فإن تدفقات ملفات IO هذه المفتوحة وغير مغلقة في JVM سوف يعيد تدويرها جميعًا عندما لم تعد تستخدم عندما يقومون بعمل GC الكامل في المرة القادمة ، لكن لا يزال من الجيد السماح لـ JVM بعمل هذه الأشياء. نفس القول القديم هو القيام بأشياءك الخاصة.