วัตถุถูกสร้างขึ้นโดยใช้ใหม่ แต่ไม่มีการดำเนินการลบที่สอดคล้องกันเพื่อรีไซเคิลหน่วยความจำที่ครอบครองโดยวัตถุ เมื่อเราใช้วัตถุให้เสร็จสมบูรณ์เราก็หยุดอ้างถึงวัตถุนั้น: เปลี่ยนการอ้างอิงของเราเป็นชี้ไปที่วัตถุอื่นหรือเป็นโมฆะ หรือกลับมาจากวิธีการเพื่อให้ตัวแปรท้องถิ่นของวิธีการไม่มีอยู่อีกต่อไปดังนั้นการอ้างอิงถึงตัวแปรท้องถิ่นเหล่านี้จะไม่ชี้ไปที่วัตถุใด ๆ วัตถุที่ไม่ได้อ้างอิงอีกต่อไปเรียกว่าขยะ กระบวนการค้นหาและรีไซเคิลวัตถุเหล่านี้เรียกว่า Garbage Collection o
Java Virtual Machines ใช้การรวบรวมขยะเพื่อให้แน่ใจว่าวัตถุอ้างอิงจะถูกเก็บไว้ในหน่วยความจำและจะเพิ่มพื้นที่เก็บข้อมูลที่ครอบครองโดยวัตถุที่ไม่สามารถเข้าถึงได้ผ่านการอ้างอิงใด ๆ ในรหัสการดำเนินการ นี่คือการรับประกันที่แข็งแกร่งว่าหากวัตถุไม่ได้รีไซเคิลหากห่วงโซ่อ้างอิงเริ่มต้นจากการอ้างอิงรูท (เช่นการอ้างอิงที่สามารถเข้าถึงได้โดยตรงในรหัสการดำเนินการ)
ในระยะสั้นเมื่อเราไม่สามารถเข้าถึงวัตถุจากรหัสที่ใช้งานได้ใด ๆ พื้นที่ที่ใช้ในการรีไซเคิล โปรดทราบว่าเราใช้คำว่า "สามารถ" ได้เพราะพื้นที่หน่วยความจำถูกนำไปรีไซเคิลจะถูกกำหนดโดยตัวเก็บขยะหรือไม่ โดยทั่วไปตัวเก็บขยะจะทำงานเฉพาะในกรณีที่จำเป็นต้องมีพื้นที่หน่วยความจำมากขึ้นหรือเพื่อหลีกเลี่ยงการล้นหน่วยความจำ อย่างไรก็ตามโปรแกรมอาจออกโดยไม่มีหน่วยความจำล้นหรือแม้กระทั่งเมื่อไม่ใกล้เคียงกับหน่วยความจำล้นดังนั้นจึงอาจไม่จำเป็นต้องมีการรวบรวมขยะเลย ในวิธีการทั้งหมดที่ดำเนินการในปัจจุบันหากตัวแปรทั้งหมดมีการอ้างอิงไปยังวัตถุและเริ่มต้นจากตัวแปรเหล่านี้การอ้างอิงไปยังวัตถุนี้ไม่สามารถพบได้ในทุกโดเมนหรือองค์ประกอบอาร์เรย์ตามห่วงโซ่อ้างอิงจากนั้นเราบอกว่าวัตถุนั้น "ไม่สามารถเข้าถึงได้"
การรีไซเคิลขยะหมายความว่าเราไม่ต้องกังวลเกี่ยวกับการอ้างอิงที่ห้อยลง ในระบบที่โปรแกรมเมอร์สามารถควบคุมได้โดยตรงเมื่อลบวัตถุโปรแกรมโปรแกรมเมอร์สามารถลบวัตถุที่วัตถุอื่นยังคงอ้างอิงได้ หากโปรแกรมเมอร์ลบวัตถุดังกล่าวการอ้างอิงที่ยังคงอ้างอิงวัตถุที่ถูกลบจะกลายเป็นโมฆะเพราะพวกเขาอ้างถึงความเงียบ
ระบบพิจารณาว่าเป็นพื้นที่หน่วยความจำที่จัดสรรได้ (แต่ในความเป็นจริงพื้นที่ได้รับการปล่อยตัว) ระบบสามารถจัดสรรพื้นที่ที่จัดสรรได้นี้ให้กับวัตถุใหม่เพื่อให้การอ้างอิงที่ชี้ไปที่พื้นที่จริง ๆ แล้วส่งผลให้วัตถุที่แตกต่างอย่างสิ้นเชิงจากสิ่งที่พวกเขาคาดหวัง ในกรณีนี้ภัยพิบัติที่คาดเดาไม่ได้อาจเกิดขึ้นเมื่อโปรแกรมใช้ค่าที่เก็บไว้ในพื้นที่นี้และดำเนินการเป็นวัตถุที่ไม่ได้เป็นของ การรวบรวมขยะแก้ปัญหาการอ้างอิงแขวนสำหรับเราเพราะวัตถุทั้งหมดที่ยังคงอ้างอิงจะไม่ได้รับการปฏิบัติเป็นคอลเลกชันขยะดังนั้นพื้นที่ที่พวกเขาครอบครองไม่สามารถปลดปล่อยได้ การรวบรวมขยะยังช่วยแก้ปัญหาการลบวัตถุเดียวกันโดยไม่ตั้งใจหลายครั้ง - ปัญหานี้อาจทำให้เกิดภัยพิบัติ การรีไซเคิลวัตถุขยะไม่จำเป็นต้องมีการแทรกแซงของเรา แต่การรีไซเคิลขยะจะใช้ทรัพยากรระบบจำนวนหนึ่ง การสร้างและการรีไซเคิลวัตถุจำนวนมากสามารถรบกวนแอปพลิเคชันที่มีความสำคัญต่อเวลาดังนั้นเมื่อออกแบบระบบดังกล่าวเราต้องจัดการกับจำนวนวัตถุที่สร้างขึ้นอย่างระมัดระวังเพื่อลดปริมาณขยะที่จะนำกลับมาใช้ใหม่
คอลเลกชันขยะไม่รับประกันว่าหน่วยความจำจะมีพื้นที่ว่างในการสร้างวัตถุใหม่เสมอ ตัวอย่างเช่นหากเรายังคงสร้างวัตถุและวางไว้ในรายการเราไม่สามารถสร้างวัตถุใหม่ได้อีกต่อไปเมื่อมีพื้นที่ไม่เพียงพอในการสร้างวัตถุใหม่และไม่มีวัตถุที่ไม่ได้อ้างอิง หากเราเก็บรายการอ้างอิงไว้ข้างต้นไปยังวัตถุที่ไม่จำเป็นอีกต่อไปการรั่วไหลของหน่วยความจำจะเกิดขึ้น คอลเลกชันขยะช่วยแก้ปัญหาการจัดสรรหน่วยความจำ (แต่ไม่ใช่ทั้งหมด) จำนวนมาก
โต้ตอบกับนักสะสมขยะ
แม้ว่าภาษา Java นั้นไม่มีวิธีใดที่ชัดเจนในการกำจัดวัตถุที่ไม่ได้ใช้งาน แต่เรายังสามารถค้นหาวัตถุที่ไม่ได้ใช้โดยเรียกตัวเก็บขยะอีกต่อไปโดยตรง วิธีการที่สะดวกสบายในคลาสรันไทม์และคลาสระบบอนุญาตให้เราโทรหาตัวเก็บขยะคำขอให้เรียกใช้ finalizers ทั้งหมดที่จะเรียกใช้หรือดูสถานะหน่วยความจำปัจจุบัน:
.Public Void GC Q: วิธีนี้ขอให้ Java Virtual Machine ใช้จ่ายวัตถุรีไซเคิลพลังงานที่ไม่ได้ใช้อีกต่อไปเพื่อที่จะสามารถนำหน่วยความจำที่ถูกครอบครองโดยวัตถุเหล่านี้อีกครั้ง
.Public void runfinalization (): วิธีนี้ขอให้ Java Virtual Machine ใช้พลังงานที่ใช้งาน finalizers ต่อไปนี้: วัตถุที่พบว่าไม่สามารถเข้าถึงได้
"Public Long Freedom (): ส่งคืนจำนวนไบต์ที่มีอยู่โดยประมาณในหน่วยความจำระบบ
・ หน่วยความจำรวมยาวสาธารณะ (): ส่งคืนจำนวนไบต์ทั้งหมดในหน่วยความจำระบบ
.Public Long MaxMemoryo: ส่งคืนจำนวนสูงสุดของหน่วยความจำระบบไบต์ที่มีให้กับเครื่องเสมือน Java หากระบบปฏิบัติการไม่มีข้อ จำกัด การใช้หน่วยความจำในเครื่องเสมือน Java ยาว ค่าสูงสุดจะถูกส่งคืน ไม่มีวิธีการใน Java ในการตั้งค่าหน่วยความจำสูงสุดของระบบ โดยปกติแล้วเครื่องเสมือน Java จะตั้งค่านี้ผ่านบรรทัดคำสั่งหรือตัวเลือกการกำหนดค่าอื่น ๆ
ในการเรียกวิธีการข้างต้นเราจำเป็นต้องได้รับการอ้างอิงไปยังวัตถุรันไทม์ปัจจุบันผ่านวิธีการคงที่ runtime.getRuntime คลาสระบบรองรับวิธี GC แบบคงที่และ runfinalization ซึ่งจะเรียกวิธีการที่สอดคล้องกันในวัตถุ Runt-ime ปัจจุบัน; กล่าวอีกนัยหนึ่งคือ System.gc () เทียบเท่ากับ runtime.getRuntime (). methods gc ()
เมื่อเรียกใช้วิธี Runtime.gc () ตัวเก็บขยะอาจไม่ได้เพิ่มหน่วยความจำพิเศษใด ๆ เนื่องจากอาจไม่มีขยะที่จะนำกลับมาใช้ใหม่และไม่ใช่นักสะสมขยะทั้งหมดที่สามารถค้นพบวัตถุที่รีไซเคิลได้ตามความต้องการ ดังนั้นการเรียกนักสะสมขยะอาจไม่มีผลกระทบใด ๆ อย่างไรก็ตามการเรียกใช้วิธี runtime.gc () เป็นที่ต้องการก่อนที่จะสร้างวัตถุจำนวนมากโดยเฉพาะอย่างยิ่งในแอพพลิเคชั่นที่สำคัญในเวลาที่ค่าใช้จ่ายเก็บขยะอาจส่งผลกระทบต่อมัน มีประโยชน์สองประการที่เป็นไปได้ในการดำเนินการ: สิ่งแรกคือเราสามารถรับหน่วยความจำได้มากที่สุดเท่าที่จะเป็นไปได้ก่อนที่จะใช้งานแอปพลิเคชันและสิ่งที่สองคือเราสามารถลดความเป็นไปได้ของนักสะสมขยะที่ทำงานในระหว่างการดำเนินงาน วิธีการต่อไปนี้เปิดตัวพื้นที่ทั้งหมดที่สามารถปล่อยได้ที่รันไทม์:
สาธารณะคงที่ vo recordful1gc () {runtime rt = runtime.getRuntime (); Long isfree = rt.freememory (); ยาวไม่มี; ทำ {wasfree = isfree; rt.runfinalization (); rt.gc (); isfree สอง rt.freememory (); } ในขณะที่ (isfree> wasfree); -วิธีการวนรอบอย่างต่อเนื่องและค่าของ freememory ยังคงเพิ่มขึ้นอย่างต่อเนื่องโดยการเรียกใช้วิธีการ runfinalization และ GC อย่างต่อเนื่อง เมื่อจำนวนหน่วยความจำอิสระไม่เพิ่มขึ้นอีกต่อไปลูปของวิธีการจะสิ้นสุดลง
เรามักจะไม่จำเป็นต้องเรียกวิธีการ runfinalization เนื่องจากวิธีการสุดท้ายเรียกว่าแบบอะซิงโครนัสโดยนักสะสมขยะ ในบางกรณีตัวอย่างเช่นเมื่อทรัพยากรที่สามารถรีไซเคิลได้โดยวิธีการสุดท้ายจะหมดลงมันจะเป็นประโยชน์ในการบังคับใช้การยุติให้มากที่สุดเท่าที่จะทำได้ แต่โปรดจำไว้ว่าเราไม่สามารถรับประกันได้ว่าวัตถุใด ๆ ที่รอการยกเลิกคือการใช้ทรัพยากรนี้ดังนั้นการทำให้เป็นไปได้
วิธี FullGC ดูเหมือนจะรุนแรงเกินไปสำหรับแอปพลิเคชันส่วนใหญ่ ในกรณีพิเศษที่จำเป็นต้องมีการเก็บรวบรวมขยะแม้ว่าจะไม่ได้รวบรวมขยะทั้งหมดโดยวิธีการโทรไปยัง System.gc เพียงครั้งเดียว แต่ก็เป็นส่วนใหญ่ของมัน ดังนั้นการโทรซ้ำจะลดอัตราการส่งออกของการรวบรวมขยะและในหลาย ๆ ระบบการโทรซ้ำเหล่านี้จะไม่มีการส่งออก