บทความนี้แนะนำหลักการของการจัดการหน่วยความจำ Java และสาเหตุของการรั่วไหลของหน่วยความจำในรายละเอียด
กลไกการจัดการหน่วยความจำ Java
ใน C ++ หากจำเป็นต้องมีหน่วยความจำเพื่อจัดสรรหน่วยความจำแบบไดนามิกโปรแกรมเมอร์จะต้องรับผิดชอบวัฏจักรชีวิตทั้งหมดของหน่วยความจำชิ้นนี้ จากแอปพลิเคชันสำหรับการจัดสรรไปจนถึงการเปิดตัวขั้นสุดท้าย กระบวนการนี้มีความยืดหยุ่นมาก แต่ยุ่งยากมาก ภาษา Java ได้ทำการเพิ่มประสิทธิภาพของตัวเองสำหรับการจัดการหน่วยความจำซึ่งเป็นกลไกการรวบรวมขยะ วัตถุหน่วยความจำเกือบทั้งหมดใน Java ได้รับการจัดสรรในหน่วยความจำ HEAP (ยกเว้นประเภทข้อมูลพื้นฐาน) และ GC (Gage Collection) จะรับผิดชอบในการรีไซเคิลหน่วยความจำโดยอัตโนมัติที่ไม่ได้ใช้อีกต่อไป
ข้างต้นเป็นสถานการณ์พื้นฐานของกลไกการจัดการหน่วยความจำ Java แต่ถ้าเราเข้าใจสิ่งนี้เท่านั้นเราจะยังคงพบกับการรั่วไหลของหน่วยความจำในการพัฒนาโครงการจริง บางคนอาจสงสัยว่าเนื่องจากกลไกการรวบรวมขยะของ Java สามารถรีไซเคิลหน่วยความจำได้โดยอัตโนมัติทำไมจึงยังคงมีการรั่วไหลของหน่วยความจำ? ในคำถามนี้เราจำเป็นต้องรู้เมื่อ GC รีไซเคิลวัตถุหน่วยความจำและวัตถุหน่วยความจำชนิดใดที่จะถูกพิจารณาว่า "ไม่ได้ใช้" โดย GC อีกต่อไป
เข้าถึงวัตถุหน่วยความจำใน Java ใช้วิธีการอ้างอิง ในรหัส Java เรารักษาตัวแปรอ้างอิงของวัตถุหน่วยความจำ ในโปรแกรม Java ตัวแปรอ้างอิงนี้สามารถเก็บไว้ในหน่วยความจำฮีปและในหน่วยความจำของรหัสสแต็ก (เหมือนกับประเภทข้อมูลพื้นฐาน) เธรด GC เริ่มติดตามจากตัวแปรอ้างอิงในสแต็กรหัสเพื่อกำหนดว่ามีการใช้หน่วยความจำใด หากเธรด GC ไม่สามารถติดตามชิ้นส่วนของหน่วยความจำฮีปด้วยวิธีนี้ GC เชื่อว่าหน่วยความจำชิ้นนี้จะไม่ถูกใช้อีกต่อไป (เพราะรหัสไม่สามารถเข้าถึงหน่วยความจำชิ้นนี้ได้อีกต่อไป)
ด้วยวิธีการจัดการหน่วยความจำกราฟที่กำกับนี้เมื่อวัตถุหน่วยความจำสูญเสียการอ้างอิงทั้งหมด GC สามารถรีไซเคิลได้ ในทางกลับกันหากวัตถุยังคงมีการอ้างอิงมันจะไม่ถูกรีไซเคิลโดย GC แม้ว่าเครื่องเสมือน Java จะโยน OutofMemoryError
การรั่วไหลของหน่วยความจำ Java
โดยทั่วไปการพูดมีสองสถานการณ์สำหรับการรั่วไหลของหน่วยความจำ ในกรณีหนึ่งในภาษา C/C ++ หน่วยความจำที่จัดสรรทั้งหมดในฮีปจะถูกลบ (เช่นการกำหนดตัวชี้ใหม่) เมื่อไม่ได้ปล่อยออกมา หน่วยความจำและวิธีการเข้าถึง (อ้างอิง) กรณีแรกคือมันได้รับการแก้ไขอย่างดีใน Java เนื่องจากการเปิดตัวกลไกการรวบรวมขยะ ดังนั้นหน่วยความจำรั่วใน Java ส่วนใหญ่อ้างถึงกรณีที่สอง
บางทีแค่พูดถึงแนวคิดนี้เป็นนามธรรมเกินไปคุณสามารถดูตัวอย่างดังกล่าวได้:
การคัดลอกรหัสมีดังนี้:
เวกเตอร์ V = เวกเตอร์ใหม่ (10);
สำหรับ (int i = 1; i <100; i ++) {
วัตถุ o = วัตถุใหม่ ();
V.Add (O);
o = null;
-
ในตัวอย่างนี้มีการอ้างอิงถึงวัตถุเวกเตอร์ V และการอ้างอิงถึงวัตถุวัตถุ o ในสแต็กรหัส ในการวนรอบสำหรับเราสร้างวัตถุใหม่อย่างต่อเนื่องจากนั้นเพิ่มลงในวัตถุเวกเตอร์แล้วล้างการอ้างอิง O คำถามคือถ้า GC เกิดขึ้นหลังจากการอ้างอิง O ว่างเปล่าวัตถุวัตถุที่เราสร้างจะถูกรีไซเคิลโดย GC หรือไม่? คำตอบคือไม่ เนื่องจากเมื่อ GC ติดตามการอ้างอิงในสแต็กรหัสจะพบการอ้างอิง V และติดตามต่อไปมันจะพบว่ามีการอ้างอิงถึงวัตถุวัตถุในพื้นที่หน่วยความจำที่ชี้ไปที่การอ้างอิง V กล่าวคือแม้ว่าการอ้างอิง O นั้นจะว่างเปล่า แต่ก็ยังมีการอ้างอิงอื่น ๆ ในวัตถุวัตถุและสามารถเข้าถึงได้ดังนั้น GC ไม่สามารถปล่อยได้ หากวัตถุวัตถุไม่มีผลต่อโปรแกรมหลังจากลูปนี้เราคิดว่าการรั่วไหลของหน่วยความจำเกิดขึ้นในโปรแกรม Java นี้
แม้ว่าการรั่วไหลของหน่วยความจำ Java จะทำลายการรั่วไหลของหน่วยความจำน้อยลงใน C/C ++ แต่โปรแกรมยังคงสามารถทำงานได้ตามปกติในกรณีส่วนใหญ่ยกเว้นบางกรณีที่โปรแกรมล่ม อย่างไรก็ตามเมื่ออุปกรณ์มือถือมีข้อ จำกัด ที่เข้มงวดเกี่ยวกับหน่วยความจำและ CPU หน่วยความจำ Java Overflow จะนำไปสู่ความไร้ประสิทธิภาพของโปรแกรมและการครอบครองหน่วยความจำที่ไม่พึงประสงค์จำนวนมาก สิ่งนี้จะทำให้ประสิทธิภาพของเครื่องทั้งหมดเสื่อมสภาพและในกรณีที่รุนแรงมันจะทำให้ outofMemoryError ถูกโยนทิ้งทำให้โปรแกรมล้มเหลว
หลีกเลี่ยงการรั่วไหลของหน่วยความจำโดยทั่วไป
โดยทั่วไปโดยไม่เกี่ยวข้องกับโครงสร้างข้อมูลที่ซับซ้อนหน่วยความจำ Java รั่วไหลออกมาเป็นวงจรชีวิตของวัตถุหน่วยความจำเกินระยะเวลาที่โปรแกรมต้องการ บางครั้งเราเรียกมันว่า "วัตถุฟรี"
ตัวอย่างเช่น:
การคัดลอกรหัสมีดังนี้:
Filesearch คลาสสาธารณะ {
ไบต์ส่วนตัว [] เนื้อหา;
ไฟล์ส่วนตัว mfile;
FileSearch สาธารณะ (ไฟล์ไฟล์) {
mfile = ไฟล์;
-
Public Boolean Hasstring (String Str) {
ขนาด int = getFilesize (mFile);
เนื้อหา = ไบต์ใหม่ [ขนาด];
โหลดไฟล์ (mfile, เนื้อหา);
สตริง s = สตริงใหม่ (เนื้อหา);
ส่งคืน s.contains (str);
-
-
ในรหัสนี้มีฟังก์ชั่น HASTRING ในคลาส Filesearch เพื่อพิจารณาว่าเอกสารมีสตริงที่ระบุหรือไม่ กระบวนการคือการโหลด mFile ลงในหน่วยความจำก่อนจากนั้นทำการตัดสิน อย่างไรก็ตามปัญหาที่นี่คือเนื้อหาถูกประกาศว่าเป็นตัวแปรอินสแตนซ์ไม่ใช่ตัวแปรท้องถิ่น ดังนั้นหลังจากฟังก์ชั่นนี้ส่งคืนข้อมูลของไฟล์ทั้งหมดยังคงอยู่ในหน่วยความจำ เห็นได้ชัดว่าเราไม่ต้องการข้อมูลเหล่านี้อีกต่อไปในอนาคตซึ่งนำไปสู่การเสียความทรงจำที่ไม่มีเหตุผล
เพื่อหลีกเลี่ยงการรั่วไหลของหน่วยความจำในกรณีนี้เราจำเป็นต้องจัดการหน่วยความจำที่จัดสรรของเราด้วยการคิดการจัดการหน่วยความจำ C/C ++ อันดับแรกคือการชี้แจงขอบเขตที่มีประสิทธิภาพของวัตถุหน่วยความจำก่อนที่จะประกาศการอ้างอิงวัตถุ วัตถุหน่วยความจำที่ถูกต้องภายในฟังก์ชั่นควรประกาศเป็นตัวแปรท้องถิ่นและผู้ที่มีวงจรชีวิตเดียวกันกับอินสแตนซ์ของคลาสควรประกาศเป็นตัวแปรอินสแตนซ์ ... และอื่น ๆ ประการที่สองอย่าลืมล้างวัตถุหน่วยความจำด้วยตนเองเมื่อไม่จำเป็นต้องใช้อีกต่อไป
ปัญหาการรั่วไหลของหน่วยความจำในโครงสร้างข้อมูลที่ซับซ้อน
ในโครงการจริงเรามักจะใช้โครงสร้างข้อมูลที่ซับซ้อนมากขึ้นเพื่อแคชข้อมูลข้อมูลที่จำเป็นในระหว่างการดำเนินการโปรแกรม บางครั้งเนื่องจากความซับซ้อนของโครงสร้างข้อมูลหรือเรามีความต้องการพิเศษบางอย่าง (ตัวอย่างเช่นข้อมูลแคชให้มากที่สุดเท่าที่จะเป็นไปได้เพื่อปรับปรุงความเร็วในการทำงานของโปรแกรม ฯลฯ ) มันเป็นเรื่องยากสำหรับเราที่จะจัดการกับข้อมูล ในโครงสร้างข้อมูล ในเวลานี้เราสามารถใช้กลไกพิเศษใน Java เพื่อป้องกันการรั่วไหลของหน่วยความจำ
เราได้แนะนำก่อนหน้านี้ว่ากลไก GC ของ Java นั้นขึ้นอยู่กับกลไกการอ้างอิงที่ติดตามหน่วยความจำ ก่อนหน้านั้นการอ้างอิงที่เราใช้กำหนดรูปแบบของ "Object O;" เท่านั้น ในความเป็นจริงนี่เป็นเพียงสถานการณ์เริ่มต้นในกลไกการอ้างอิง Java และมีวิธีการอ้างอิงอื่น ๆ นอกจากนี้ ด้วยการใช้กลไกการอ้างอิงพิเศษเหล่านี้และรวมกับกลไก GC เราสามารถบรรลุผลบางอย่างที่เราต้องการ
วิธีการอ้างอิงหลายวิธีใน Java
มีหลายวิธีในการอ้างถึงในชวาคือ: การอ้างอิงที่แข็งแกร่ง, การอ้างอิงที่อ่อนนุ่ม, การอ้างอิงที่อ่อนแอและการอ้างอิงเสมือนจริง ต่อไปก่อนอื่นเราเข้าใจถึงความสำคัญของวิธีการอ้างอิงเหล่านี้โดยละเอียด
คำพูดที่แข็งแกร่ง
การอ้างอิงที่ใช้ในเนื้อหาที่เราแนะนำมาก่อนคือการอ้างอิงที่แข็งแกร่งทั้งหมดซึ่งเป็นการอ้างอิงที่ใช้กันมากที่สุด หากวัตถุมีการอ้างอิงที่แข็งแกร่งมันจะคล้ายกับความจำเป็นประจำวันที่สำคัญและตัวเก็บขยะจะไม่รีไซเคิล เมื่อพื้นที่หน่วยความจำไม่เพียงพอเครื่องเสมือน Java ค่อนข้างจะโยนข้อผิดพลาด outofMemoryError เพื่อทำให้โปรแกรมสิ้นสุดลงอย่างผิดปกติกว่าการรีไซเคิลวัตถุที่มีการอ้างอิงที่แข็งแกร่งเพื่อแก้ปัญหาหน่วยความจำ
การประนีประนอม
การใช้งานทั่วไปของคลาส Softreference สำหรับแคชที่ไวต่อหน่วยความจำ หลักการของ Softreference คือเพื่อให้แน่ใจว่าการอ้างอิงที่อ่อนนุ่มทั้งหมดจะถูกล้างก่อนที่ JVM จะรายงานหน่วยความจำไม่เพียงพอเมื่อทำการอ้างอิงถึงวัตถุ ประเด็นสำคัญคือตัวเก็บขยะอาจปล่อยวัตถุที่สามารถเข้าถึงได้ (หรืออาจไม่ใช่) ที่ใช้งานง่ายในรันไทม์ ไม่ว่าวัตถุจะเป็นอิสระหรือไม่นั้นขึ้นอยู่กับอัลกอริทึมของนักสะสมขยะและปริมาณหน่วยความจำที่มีอยู่เมื่อตัวเก็บขยะกำลังทำงานอยู่
ความอ่อนแอ
การใช้งานทั่วไปของคลาสที่อ่อนแอคือการทำแผนที่เป็นปกติ (การทำแผนที่ที่เป็นที่ยอมรับ) นอกจากนี้การอ้างอิงที่อ่อนแอยังมีประโยชน์สำหรับวัตถุที่มีอายุการใช้งานค่อนข้างยาวนานและค่าใช้จ่ายด้านการพักผ่อนหย่อนใจต่ำ ประเด็นสำคัญคือหากพบวัตถุที่สามารถเข้าถึงได้อย่างอ่อนแอในระหว่างการรันตัวเก็บขยะวัตถุที่อ้างอิงโดยการอ้างอิงที่อ่อนแอจะถูกปล่อยออกมา อย่างไรก็ตามโปรดทราบว่าตัวสะสมขยะอาจต้องทำงานหลายครั้งก่อนที่จะสามารถค้นหาและปล่อยวัตถุที่เข้าถึงได้อย่างอ่อนแอ
การอ้างสิทธิ์
คลาส phantomreference สามารถใช้เพื่อติดตามคอลเลกชันที่กำลังจะมาถึงของวัตถุอ้างอิงเท่านั้น ในทำนองเดียวกันมันยังสามารถใช้ในการดำเนินการล้างก่อนชัน phantomreference จะต้องใช้กับคลาส referencequeue จำเป็นต้องใช้ referenceQueue เพราะสามารถทำหน้าที่เป็นกลไกการแจ้งเตือน เมื่อตัวรวบรวมขยะกำหนดว่าวัตถุเป็นวัตถุการเข้าถึงเสมือนจริงวัตถุ phantomreference จะถูกวางไว้บนอ้างอิงของมัน การวางวัตถุ phantomreference บน ReferenceQueue เป็นการแจ้งเตือนที่ระบุว่าวัตถุที่อ้างอิงโดยวัตถุ phantomreference สิ้นสุดลงและพร้อมสำหรับการรวบรวม สิ่งนี้ช่วยให้คุณสามารถดำเนินการก่อนที่หน่วยความจำที่ถูกครอบครองโดยวัตถุจะถูกรีไซเคิล การอ้างอิงและอ้างอิงจะใช้ร่วมกับ ReferenceQueue
GC, Reference และ ReferenceQueue
A. GC ไม่สามารถลบหน่วยความจำของวัตถุที่มีการอ้างอิงที่แข็งแกร่ง
B. GC พบหน่วยความจำวัตถุที่มีการอ้างอิงที่อ่อนนุ่มเท่านั้นจากนั้น:
①ฟิลด์อ้างอิงของวัตถุ softreference ถูกตั้งค่าเป็น null เพื่อให้วัตถุไม่ได้หมายถึงวัตถุฮีปอีกต่อไป
②วัตถุฮีปที่อ้างอิงโดย softreference ถูกประกาศว่าเป็นขั้นสุดท้าย
③เมื่อวิธีการสุดท้าย () ของวัตถุฮีปถูกเรียกใช้และหน่วยความจำที่ถูกครอบครองโดยวัตถุจะถูกปล่อยออกมาวัตถุ softreference จะถูกเพิ่มลงในอ้างอิง (หากมีอยู่หลัง)
C. GC ค้นพบหน่วยความจำวัตถุที่มีการอ้างอิงที่อ่อนแอเท่านั้นจากนั้น:
①ฟิลด์อ้างอิงของวัตถุที่อ่อนแอถูกตั้งค่าเป็นโมฆะเพื่อให้วัตถุไม่ได้หมายถึงวัตถุฮีปอีกต่อไป
②วัตถุฮีปที่อ้างอิงโดยการอ้างอิงที่อ่อนแอนั้นถูกประกาศว่าเป็นขั้นสุดท้าย
③เมื่อวิธีการสุดท้าย () ของวัตถุฮีปถูกเรียกใช้และหน่วยความจำที่ถูกครอบครองโดยวัตถุจะถูกปล่อยออกมาวัตถุที่อ่อนแอจะถูกเพิ่มลงในอ้างอิงของมัน (หากมีอยู่หลัง)
D. GC ค้นพบหน่วยความจำวัตถุที่มีการอ้างอิงเสมือนจริงเท่านั้น:
①วัตถุฮีปที่อ้างอิงโดย phantomreference ถูกประกาศว่าเป็นขั้นสุดท้าย
② Phantomreference ถูกเพิ่มเข้าไปใน referenceQueue ก่อนที่จะปล่อยวัตถุฮีป
ประเด็นต่อไปนี้เป็นสิ่งที่ควรค่าแก่การสังเกต:
1. GC จะไม่พบวัตถุหน่วยความจำที่อ้างอิงแบบอ่อนโดยทั่วไป
2. การค้นพบและการเปิดตัวการอ้างอิงที่อ่อนแอของ GC ไม่ได้เกิดขึ้นทันที
3. เมื่อมีการเพิ่มการอ้างอิงที่อ่อนนุ่มและการอ้างอิงที่อ่อนแอลงใน ReferenceQueue การอ้างอิงไปยังหน่วยความจำจริงได้รับการตั้งค่าให้ว่างเปล่าและหน่วยความจำที่เกี่ยวข้องได้รับการปล่อยออกมา เมื่อเพิ่มการอ้างอิงเสมือนไปยัง ReferenceQueue หน่วยความจำยังไม่ได้รับการเผยแพร่และยังสามารถเข้าถึงได้
ผ่านการแนะนำข้างต้นฉันเชื่อว่าคุณมีความเข้าใจบางอย่างเกี่ยวกับกลไกการอ้างอิง Java และความคล้ายคลึงและความแตกต่างของวิธีการอ้างอิงหลายวิธี เพียงแค่แนวคิดอาจเป็นนามธรรมเกินไป
การคัดลอกรหัสมีดังนี้:
String str = ใหม่ ("สวัสดี");
ReferenceQueue <String> RQ = New ReferenceQueue <String> ();
Weakreference <String> WF = New Weakreference <String> (Str, RQ);
str = null;
String str1 = wf.get ();
// ถ้าวัตถุ "hello" ไม่ได้รีไซเคิล rq.poll () จะส่งคืน null
อ้างอิง <?
ในรหัสข้างต้นให้ความสนใจกับทั้งสองสถานที่⑤⑥ หากวัตถุ "สวัสดี" ไม่ได้รีไซเคิล wf.get () จะส่งคืนวัตถุสตริง "สวัสดี" RQ.Poll () จะส่งคืนค่า NULL NULL, RQ.POLL () ส่งคืนวัตถุอ้างอิง แต่ไม่มีการอ้างอิงถึงวัตถุ STR ในวัตถุอ้างอิงนี้ (phantomReference นั้นแตกต่างจากความอ่อนแอและ softreference)
การประยุกต์ใช้กลไกการอ้างอิงร่วมกันและโครงสร้างข้อมูลที่ซับซ้อน
โดยการทำความเข้าใจกลไก GC กลไกการอ้างอิงและการรวมกับ ReferenceQueue เราสามารถใช้ประเภทข้อมูลที่ซับซ้อนบางชนิดที่ป้องกันไม่ให้หน่วยความจำล้น
ตัวอย่างเช่น Softreference มีลักษณะของการสร้างระบบแคชดังนั้นเราจึงสามารถใช้ระบบแคชอย่างง่ายร่วมกับตารางแฮช สิ่งนี้ไม่เพียง แต่จะช่วยให้มั่นใจได้ว่าข้อมูลจำนวนมากสามารถแคชได้ แต่ยังทำให้มั่นใจได้ว่าเครื่องเสมือน Java จะไม่ส่งผลงาน outofmemoryError เนื่องจากการรั่วไหลของหน่วยความจำ กลไกการแคชนี้เหมาะอย่างยิ่งสำหรับสถานการณ์ที่วัตถุหน่วยความจำมีวงจรชีวิตที่ยาวนานและเวลาในการสร้างวัตถุหน่วยความจำค่อนข้างยาวเช่นรายการแคชครอบคลุมภาพ ฯลฯ สำหรับบางกรณีที่วงจรชีวิตยาว แต่ค่าใช้จ่ายของการสร้างวัตถุหน่วยความจำไม่ใหญ่การใช้การอ้างอิงที่อ่อนแอสามารถบรรลุการจัดการหน่วยความจำที่ดีขึ้น
สำเนาของซอร์สโค้ดของ SofthashMap นั้นแนบมาด้วย
การคัดลอกรหัสมีดังนี้:
แพ็คเกจ com. ***. widget;
//: softhashmap.java
นำเข้า Java.util
นำเข้า java.lang.ref
นำเข้า Android.util.log;
SOFTHASHMAP ระดับสาธารณะขยายบทคัดย่อ {
/** hashmap ภายในที่จะถือ softreference
แผนที่สุดท้ายส่วนตัวแฮช = ใหม่ hashmap ();
/** จำนวนการอ้างอิง "ยาก" ที่จะถือภายใน
INT สุดท้ายส่วนตัว hard_size;
/** รายการ FIFO ของการอ้างอิงอย่างหนักลำดับการเข้าถึงล่าสุด
LinkedList LinkedList ส่วนตัว = new LinkedList ();
/** คิวการอ้างอิงสำหรับวัตถุที่ถูกล้างออก
คิวอ้างอิงส่วนตัว = new ReferenceQueue ();
// หมายเลขอ้างอิงที่แข็งแกร่ง
Public SofthashMap () {สิ่งนี้ (100);
SofthashMap สาธารณะ (int hardsize) {hard_size = hardsize;}
วัตถุสาธารณะรับ (คีย์วัตถุ) {
ผลลัพธ์ของวัตถุ = null;
// เราได้รับ softreference ที่แสดงโดยคีย์นั้น
softreference soft_ref = (softreference) hash.get (คีย์);
ถ้า (soft_ref! = null) {
// จาก softreference ที่เราได้รับค่าซึ่งสามารถเป็นได้
// null ถ้ามันไม่ได้อยู่ในแผนที่หรือถูกลบออกใน
// วิธี processQueue () ที่กำหนดไว้ด้านล่าง
ผลลัพธ์ = soft_ref.get ();
if (result == null) {
// หากเก็บค่าขยะให้ลบไฟล์
// รายการจาก HashMap
hash.remove (กุญแจ);
} อื่น {
// ตอนนี้เราเพิ่มวัตถุนี้ลงในจุดเริ่มต้นของยาก
// คิวอ้างอิง
// หนึ่งครั้งเนื่องจากการค้นหาคิว FIFO นั้นช้าดังนั้น
// เราไม่ต้องการค้นหาในแต่ละครั้งเพื่อลบ
// ซ้ำกัน
// เก็บวัตถุการใช้งานล่าสุดไว้ในหน่วยความจำ
hardcache.addfirst (ผลลัพธ์);
if (hardcache.size ()> hard_size) {
// ลบรายการสุดท้ายหากรายการนานกว่า hard_size
hardcache.removelast ();
-
-
-
ผลตอบแทน;
-
/** เรากำหนดคลาสย่อยของเราเองของ Softreference ซึ่งมีอยู่
ไม่เพียง แต่ค่า แต่ยังเป็นกุญแจสำคัญในการค้นหา
รายการใน Hashmap หลังจากเก็บขยะ
SoftValue คลาสคงที่ส่วนตัวขยาย softreference {
คีย์วัตถุสุดท้ายส่วนตัว
/** คุณรู้หรือไม่ว่าชั้นนอกสามารถเข้าถึงข้อมูลส่วนตัวได้
สมาชิกและวิธีการเรียนชั้นใน?
ฉันคิดว่ามันเป็นเพียงชั้นเรียนชั้นในที่สามารถเข้าถึง
ข้อมูลส่วนตัวของชั้นนอก
เข้าถึงสมาชิกส่วนตัวของชั้นเรียนภายในภายในภายใน
ระดับ. */
Private SoftValue (Object K, Key Object, ReferenceQueue q) {
super (k, q);
. key = key;
-
-
/** ที่นี่เราผ่านการอ้างอิงและลบขยะ
รวบรวมวัตถุ softvalue จาก hashmap โดยดูพวกเขา
UP โดยใช้ SoftValue.key Data Member
โมฆะสาธารณะ processQueue () {
SoftValue SV;
ในขณะที่ ((sv = (softvalue) queue.poll ())! = null) {
if (sv.get () == null) {
log.e ("processqueue", "null");
} อื่น {
log.e ("processqueue", "ไม่ใช่ null");
-
hash.remove (sv.key); // เราสามารถเข้าถึงข้อมูลส่วนตัว!
log.e ("softhashmap", "release" + sv.key);
-
-
/** ที่นี่เราใส่คีย์คู่ค่าไว้ใน HashMap โดยใช้
วัตถุ softvalue
วัตถุสาธารณะใส่ (คีย์วัตถุค่าวัตถุ) {
ProcessQueue ();
log.e ("softhashmap", "ใส่ลงใน" + คีย์);
ส่งคืน hash.put (คีย์, softValue ใหม่ (ค่า, คีย์, คิว));
-
ลบวัตถุสาธารณะ (คีย์วัตถุ) {
ProcessQueue ();
กลับ hash.remove (กุญแจ);
-
โมฆะสาธารณะ Clear () {
hardcache.clear ();
ProcessQueue ();
hash.clear ();
-
ขนาด int สาธารณะ () {
ProcessQueue ();
คืน hash.size ();
-
ชุดแรกเริ่มต้น () {
// ไม่ไม่คุณอาจไม่ทำอย่างนั้น !!!
โยน unsupportedoperationexception ใหม่ ();
-
-