มีเมธอดในเธรดที่ทุกคนมักเรียกกัน นั่นคือ ThreadLocal อย่างไรก็ตาม ThreadLocal ยังจะพบกับปัญหาที่ยากขึ้นในการประมวลผลหน่วยความจำ และหน่วยความจำรั่วไหลบางอย่างก็จะเกิดขึ้นเสมอ บทความนี้จะใช้ตัวอย่างการรั่วไหลเพื่อวิเคราะห์สำหรับทุกคน และยังช่วยให้คุณเข้าใจสถานการณ์บางอย่างในการรั่วไหล และเสนอวิธีแก้ปัญหาที่สอดคล้องกันกับ ThreadLocal
1. ตัวอย่างการรั่วไหล
รายการคลาสภายในแบบคงที่ของ ThreadLocalMap:
รายการคลาสคงที่ขยาย WeakReference<ThreadLocal<?>> { /** ค่าที่เกี่ยวข้องกับ ThreadLocal นี้ */ ค่าวัตถุ รายการ (ThreadLocal<?> k, Object v) { ซุปเปอร์(k); ค่า = โวลต์; - -
ThreadLocalMap ใช้รายการคลาสภายในแบบคงที่เพื่อใช้พื้นที่เก็บข้อมูล <k, v> และรายการสืบทอดคลาส WeakReference ดังนั้นคีย์ใน ThreadLocalMap จึงเป็นการอ้างอิงที่อ่อนแอไปยัง ThreadLocal
เนื่องจาก ThreadLocalMap ใช้การอ้างอิงที่ไม่รัดกุมของ ThreadLocal เป็นคีย์ เมื่อ ThreadLocal นี้ไม่มีการอ้างอิงที่รัดกุมภายนอก มันจะเป็น GC ในขณะนี้ รายการที่มีคีย์ว่างจะปรากฏใน ThreadLocalMap แน่นอนว่าค่าของรายการนี้จะไม่สามารถเข้าถึงได้
ในกรณีนี้ หากเธรดการทำงานปัจจุบันยังไม่สิ้นสุด ค่าที่มีคีย์ null จะถูกอ้างอิงอย่างแน่นหนาโดย Entry และ Entry จะถูกอ้างอิงอย่างยิ่งโดย ThreadLocalMap ของเธรดปัจจุบัน ทำให้ค่านี้ไม่เคยถูก GCed ทำให้เกิดหน่วยความจำ รั่ว.
2. วิธีแก้ปัญหา
เมธอด cleanSomeSlots() และ expungeStaleEntry() ของ ThreadLocalMap สามารถล้างค่าด้วยคีย์ Null ได้ ในเมธอด set(), get() และ Remove() ของ ThreadLocal, cleanSomeSlots() หรือ expungeStaleEntry() จะถูกเรียกเพื่อล้างค่าทั้งหมดด้วยคีย์ null ใน ThreadLocalMap
ข้างต้นเป็นวิธีการแก้ปัญหาการรั่วไหลของหน่วยความจำ Java ThreadLocal แน่นอนว่านี่อาจมีบทบาทเฉพาะในการรั่วไหลของหน่วยความจำเท่านั้น ท้ายที่สุดแล้ว มันเป็นเพียงความชัดเจนและไม่มีการรับประกันว่ามันจะไม่เกิด ขึ้น