คนเก็บขยะใน Java คืออะไร?


105

ฉันยังใหม่กับ Java และสับสนเกี่ยวกับตัวเก็บขยะใน Java มันทำอะไรได้จริงและจะเกิดขึ้นเมื่อไหร่ โปรดอธิบายคุณสมบัติบางประการของตัวรวบรวมขยะใน Java



10
บางครั้งควรอ่านบทในหนังสือดีๆโดยคาดหวังว่าจะเข้าใจเรื่องที่ซับซ้อนจากคำตอบของคำถามเดียว
Ian Ringrose

4
@ เอียนมันเป็นคำถามที่คล้ายกัน แต่ไม่ใช่คำถามที่ซ้ำกัน และคำถามที่reeksของบ้าน
NullUserException

คำตอบ:


120

ตัวรวบรวมขยะเป็นโปรแกรมที่ทำงานบนJava Virtual Machineซึ่งกำจัดอ็อบเจ็กต์ที่ไม่ได้ใช้โดยแอ็พพลิเคชัน Java อีกต่อไป เป็นการจัดการหน่วยความจำอัตโนมัติรูปแบบหนึ่ง

เมื่อแอ็พพลิเคชัน Java ทั่วไปกำลังทำงานแอปพลิเคชันจะสร้างอ็อบเจ็กต์ใหม่เช่นStrings และFiles แต่เมื่อผ่านไประยะหนึ่งอ็อบเจ็กต์เหล่านั้นจะไม่ถูกใช้อีกต่อไป ตัวอย่างเช่นดูรหัสต่อไปนี้:

for (File f : files) {
    String s = f.getName();
}

ในโค้ดข้างต้นString sจะถูกสร้างขึ้นบนทวนของแต่ละforวง ซึ่งหมายความว่าในการทำซ้ำทุกครั้งจะมีการจัดสรรหน่วยความจำเล็กน้อยเพื่อสร้างStringวัตถุ

กลับไปที่โค้ดเราจะเห็นว่าเมื่อมีการดำเนินการซ้ำเพียงครั้งเดียวในการทำซ้ำครั้งถัดไปStringวัตถุที่สร้างขึ้นในการทำซ้ำก่อนหน้านี้จะไม่ถูกใช้อีกต่อไป - ตอนนี้วัตถุนั้นถือว่าเป็น "ขยะ"

ในที่สุดเราจะเริ่มได้รับขยะจำนวนมากและหน่วยความจำจะถูกใช้สำหรับวัตถุที่ไม่ได้ใช้อีกต่อไป หากยังคงดำเนินต่อไปในที่สุด Java Virtual Machine ก็จะไม่มีพื้นที่ในการสร้างวัตถุใหม่

นั่นคือจุดที่คนเก็บขยะก้าวเข้ามา

คนเก็บขยะจะมองหาวัตถุที่ไม่ได้ใช้งานอีกต่อไปและกำจัดทิ้งทำให้หน่วยความจำว่างเพื่อให้วัตถุใหม่อื่น ๆ สามารถใช้หน่วยความจำนั้นได้

ใน Java จัดการหน่วยความจำได้รับการดูแลโดยการเก็บขยะ แต่ในภาษาอื่น ๆ เช่น C ซึ่งเป็นหนึ่งในความต้องการที่จะดำเนินการจัดการหน่วยความจำของพวกเขาโดยใช้ฟังก์ชั่นของตัวเองเช่นและmalloc freeการจัดการหน่วยความจำเป็นหนึ่งในสิ่งเหล่านั้นที่ง่ายต่อการทำผิดพลาดซึ่งอาจนำไปสู่สิ่งที่เรียกว่าการรั่วไหลของหน่วยความจำ - สถานที่ที่หน่วยความจำไม่ได้รับการเรียกคืนเมื่อไม่ได้ใช้งานอีกต่อไป

รูปแบบการจัดการหน่วยความจำอัตโนมัติเช่นการเก็บขยะทำให้โปรแกรมเมอร์ไม่ต้องกังวลกับปัญหาการจัดการหน่วยความจำมากนักดังนั้นเขาจึงสามารถมุ่งเน้นไปที่การพัฒนาแอปพลิเคชันที่ต้องการพัฒนาได้มากขึ้น


จะเป็นเรื่องจริงหรือไม่ที่จะบอกว่าแอปพลิเคชัน java ที่ทำงานบนคอมพิวเตอร์แล้วมีฟังก์ชันการเก็บขยะสองฟังก์ชัน หนึ่งเดียวกับเครื่องเสมือน Java แล้วหนึ่งในเครื่องจริงที่รัน windows? (หรือระบบปฏิบัติการอื่น ๆ )
Lealo

ไม่โดยทั่วไปแอปพลิเคชัน Java จะทำงานเฉพาะเมื่อมี JRE อยู่ ดังนั้นจึงต้องมีฟังก์ชันการเก็บขยะของ JVM เท่านั้น! @Lealo
Am_I_Helpful

18

มันปลดปล่อยหน่วยความจำที่จัดสรรให้กับอ็อบเจ็กต์ที่โปรแกรมไม่ได้ใช้งานอีกต่อไปดังนั้นชื่อ "ขยะ" ตัวอย่างเช่น:

public static Object otherMethod(Object obj) {
    return new Object();
}

public static void main(String[] args) {
    Object myObj = new Object();
    myObj = otherMethod(myObj);
    // ... more code ...  
}

ฉันรู้ว่านี่เป็นสิ่งที่ประดิษฐ์ขึ้นอย่างมาก แต่ที่นี่หลังจากที่คุณเรียกotherMethod()ว่าต้นฉบับที่Objectสร้างขึ้นนั้นกลับไม่สามารถเข้าถึงได้และนั่นคือ "ขยะ" ที่เก็บขยะ

ใน Java GC จะทำงานโดยอัตโนมัติ แต่คุณสามารถเรียกมันอย่างชัดเจนSystem.gc()และพยายามบังคับให้เก็บขยะที่สำคัญ ดังที่ Pascal Thivent ชี้ให้เห็นคุณไม่ควรทำเช่นนี้จริงๆและอาจส่งผลเสียมากกว่าผลดี (ดูคำถามนี้ )

สำหรับข้อมูลเพิ่มเติมโปรดดูรายการวิกิพีเดียเกี่ยวกับการรวบรวมขยะและการปรับแต่งการรวบรวมขยะ (จาก Oracle)


1
AFAIK System.gc()ไม่ได้บังคับให้ GC ทำงาน
Itay Karo

1
+1 สำหรับตัวอย่างโค้ดที่ดี โปรดทราบว่า GC สามารถทำลายได้อย่างสมบูรณ์myObjก่อนที่จะมีการเรียกotherMethodใช้เนื่องจากmyObjไม่สามารถเข้าถึงได้อีกต่อไปในตอนนั้น
Billy ONeal

@ อิตาลีฉันเชื่อว่าเป็นการใช้งานเฉพาะ
NullUserException

2
ฉันเชื่อว่าไม่ควรโทรSystem.gc()มาประเด็นทั้งหมดของการมี GC คือไม่ต้องทำอย่างนั้น
Pascal Thivent

ด้วยการวิเคราะห์การหลีกเลี่ยง ( en.wikipedia.org/wiki/Escape_analysis ) อาจเป็นไปได้ว่า JVM อาจไม่ได้จัดสรรวัตถุตั้งแต่แรกในตัวอย่างนี้ การสร้างวัตถุทั้งหมดสามารถ (ในทางทฤษฎี) ได้รับการปรับให้เหมาะสมที่สุด การดำเนินการขึ้นอยู่กับหลักสูตร
mikera

15

ออบเจ็กต์จะมีสิทธิ์ได้รับ Garbage collection หรือ GC หากไม่สามารถเข้าถึงได้จากเธรดที่ใช้งานอยู่หรือโดยการอ้างอิงแบบคงที่

กล่าวอีกนัยหนึ่งคุณสามารถพูดได้ว่าออบเจ็กต์มีสิทธิ์สำหรับการรวบรวมขยะหากการอ้างอิงทั้งหมดเป็นโมฆะ การอ้างอิงแบบไซคลิกจะไม่นับเป็นการอ้างอิงดังนั้นหากอ็อบเจกต์ A มีการอ้างอิงถึงอ็อบเจ็กต์ B และอ็อบเจกต์ B มีการอ้างอิงถึงอ็อบเจ็กต์ A และอ็อบเจ็กต์ B ไม่มีการอ้างอิงอื่น ๆ แบบเรียลไทม์ดังนั้นอ็อบเจ็กต์ A และ B ทั้งสองจะมีสิทธิ์สำหรับการรวบรวมขยะ


Heap Generations for Garbage Collection -

วัตถุ Java ถูกสร้างขึ้นใน HeapและHeapแบ่งออกเป็นสามส่วนหรือหลายชั่วอายุคนเพื่อประโยชน์ในการรวบรวมขยะใน Java สิ่งเหล่านี้เรียกว่าYoung (New) generation, Tenured (Old) Generation และ Perm Area of the heap

Java Heap Space New Generationถูกแบ่งออกเป็นสามส่วนที่เรียกว่า Eden space, Survivor 1 และ Survivor 2 space เมื่อวัตถุที่สร้างขึ้นครั้งแรกในกองของตนได้รับการสร้างขึ้นในรุ่นใหม่ภายในพื้นที่ Eden และหลังคอลเลกชันเล็กน้อยขยะตามมาถ้าวัตถุมีชีวิตอยู่ของมันได้รับการย้ายไปยังผู้รอดชีวิตที่ 1 และ 2 แล้วรอดชีวิตก่อนที่จะเก็บขยะที่สำคัญย้ายวัตถุที่รุ่นเก่าหรือดำรงตำแหน่ง

Perm spaceของ Java Heap คือที่ที่ JVM เก็บ Metadata เกี่ยวกับคลาสและวิธีการต่าง ๆ String pool และรายละเอียดระดับ Class

ฮีปรุ่นสำหรับการรวบรวมขยะ

ดูข้อมูลเพิ่มเติมได้ที่นี่: Garbage Collection


คุณไม่สามารถบังคับให้ JVM เรียกใช้ Garbage Collection แม้ว่าคุณจะสามารถร้องขอโดยใช้ไฟล์ System.gc()หรือRuntime.gc()วิธีการได้

ใน java.lang.System

public static void gc() {
    Runtime.getRuntime().gc();  
}

ใน java.lang.Runtime

public native void gc();  // note native  method

Mark and Sweep Algorithm -

นี่เป็นหนึ่งในอัลกอริทึมยอดนิยมที่ใช้ในการรวบรวมขยะ อัลกอริทึมการรวบรวมขยะใด ๆ ต้องดำเนินการพื้นฐาน 2 อย่าง หนึ่งควรจะสามารถตรวจจับวัตถุที่ไม่สามารถเข้าถึงได้ทั้งหมดและประการที่สองต้องเรียกคืนพื้นที่ฮีปที่ใช้โดยวัตถุขยะและทำให้พื้นที่ว่างสำหรับโปรแกรมอีกครั้ง

การดำเนินการข้างต้นดำเนินการโดย Mark และ Sweep Algorithm ในสองขั้นตอน:

  1. ทำเครื่องหมายเฟส
  2. กวาดเฟส

อ่านรายละเอียดเพิ่มเติมได้ที่นี่ - Mark and Sweep Algorithm


6

คนเก็บขยะบอกเป็นนัยว่าวัตถุที่โปรแกรมไม่ต้องการอีกต่อไปคือ "ขยะ" และสามารถโยนทิ้งได้


6

Garbage Collector เป็นส่วนหนึ่งของ JRE ที่ทำให้แน่ใจว่าอ็อบเจ็กต์ที่ไม่ได้อ้างอิงจะถูกปลดปล่อยจากหน่วยความจำ
โดยปกติจะทำงานเมื่อแอปของคุณมีหน่วยความจำไม่เพียงพอ AFAIK มีกราฟที่แสดงถึงการเชื่อมโยงระหว่างวัตถุและวัตถุที่แยกได้
เพื่อประหยัดประสิทธิภาพของอ็อบเจ็กต์ปัจจุบันที่จัดกลุ่มเป็นรุ่น ๆ ทุกครั้งที่ GC สแกนอ็อบเจ็กต์และพบว่ายังคงอ้างอิงจำนวนการสร้างโดยเพิ่มขึ้นทีละ 1 (ถึงค่าสูงสุดสูงสุดบางค่า 3 หรือ 4 ฉันคิดว่า) และรุ่นใหม่จะถูกสแกนก่อน (วัตถุที่สั้นที่สุดในหน่วยความจำอาจไม่จำเป็นอีกต่อไป) ดังนั้นไม่ใช่ทุกวัตถุที่ถูกสแกนทุกครั้งที่ GC ทำงาน
อ่านนี้สำหรับข้อมูลเพิ่มเติม


@quantumSoup คุณเป็นไปได้กับสิ่งนี้หรือไม่? ฉันเชื่อว่าการเก็บขยะบางประเภท (ราคาแพงกว่า) จะเกิดขึ้นก็ต่อเมื่อกองขยะเต็ม
Pablo Fernandez

2
@quantumSoup - ขึ้นอยู่กับการใช้งาน GC ของ JRE ในหลาย ๆ กรณี GC ไม่ทำงานอย่างต่อเนื่อง แต่จะทำงานเมื่อแอปของคุณไม่สามารถจัดสรรออบเจ็กต์ได้เนื่องจากฮีปเต็ม JVM ของ HotSpot ล่าสุดมี GC แบบขนาน แต่ไม่ได้เปิดใช้งานตามค่าเริ่มต้น
Stephen C

คำตอบนี้มุ่งเน้นไปที่กลไกมากเกินไป คำถามคือ "คนเก็บขยะคืออะไร" ไม่ใช่ "คนเก็บขยะทำงานอย่างไร"
Billy ONeal

@quantum: ทำให้ค่า -1 เป็นกลางเพราะ: การเรียนรู้นั่นคือเพจนี้มีไว้เพื่ออะไรใช่มั้ย? เพื่อเรียนรู้ว่าคุณต้องทำผิดพลาด การลงโทษความผิดพลาดทำให้คนไม่เรียนรู้ หวังว่าคุณจะเห็นด้วยในจุดนั้น และบางทีคุณอาจทำผิดพลาดที่นี่
erikbwork

1
@erikb: ด้วยเหตุผลดังกล่าวจะไม่มีการโหวตลงคะแนนใด ๆ และการลงคะแนนเป็นสิ่งที่จำเป็นในการกำจัดคำตอบที่ค่อนข้างแย่ เห็นได้ชัดว่า OP เป็นผู้เริ่มต้นและการทำงานภายในเฉพาะของ GC ก็ไม่สำคัญกับคำถามที่ถาม เนื่องจากคำตอบนี้ไม่ตอบคำถามที่ถาม (คำตอบที่แตกต่างออกไป) การโหวตลดลงจึงมีเหตุผลอย่างสมบูรณ์แบบ
Billy ONeal

3

เครื่องเก็บขยะช่วยให้คอมพิวเตอร์ของคุณสามารถจำลองคอมพิวเตอร์ที่มีหน่วยความจำไม่สิ้นสุด ส่วนที่เหลือเป็นเพียงกลไก

ทำได้โดยการตรวจจับเมื่อไม่สามารถเข้าถึงหน่วยความจำได้อีกต่อไปจากรหัสของคุณและส่งคืนชิ้นส่วนเหล่านั้นไปยังร้านค้าฟรี

แก้ไข: ใช่ลิงค์สำหรับ C # แต่ C # และ Java เหมือนกันในเรื่องนี้


มีคำถามเกี่ยวกับ SO เกี่ยวกับความแตกต่างระหว่าง java และ GC ของ C #: stackoverflow.com/questions/492703/c-vs-java-garbage-collector
NullUserException

3

หลายคนคิดว่าการเก็บขยะจะรวบรวมและทิ้งสิ่งของที่ตายแล้ว
ในความเป็นจริงการเก็บขยะของ Java กำลังทำสิ่งที่ตรงกันข้าม! มีการติดตามวัตถุสดและทุกสิ่งที่กำหนดขยะ

เมื่ออ็อบเจ็กต์ไม่ได้ใช้อีกต่อไปตัวรวบรวมขยะจะเรียกคืนหน่วยความจำพื้นฐานและนำกลับมาใช้ใหม่สำหรับการจัดสรรอ็อบเจ็กต์ในอนาคต ซึ่งหมายความว่าจะไม่มีการลบอย่างชัดเจนและไม่มีการให้หน่วยความจำกลับไปที่ระบบปฏิบัติการ ในการพิจารณาว่าวัตถุใดไม่ได้ใช้งานแล้ว JVM จะเรียกใช้สิ่งที่เรียกว่าอัลกอริธึมมาร์คและกวาดเป็นระยะ ๆ

ตรวจสอบข้อมูลเพิ่มเติมได้ที่ http://javabook.compuware.com/content/memory/how-garbage-collection-works.aspx


1

เพื่อให้เป็นคำที่ง่ายที่สุดที่แม้แต่ผู้ที่ไม่ใช่โปรแกรมเมอร์ก็สามารถเข้าใจได้เมื่อโปรแกรมประมวลผลข้อมูลมันจะสร้างข้อมูลระดับกลางและพื้นที่จัดเก็บข้อมูล (ตัวแปรอาร์เรย์ข้อมูลเมตาของวัตถุบางอย่างเป็นต้น) สำหรับข้อมูลนั้น

เมื่ออ็อบเจ็กต์เหล่านี้ถูกเข้าถึงข้ามฟังก์ชันหรือเกินขนาดที่กำหนดอ็อบเจ็กต์เหล่านี้จะถูกจัดสรรจากฮีปส่วนกลาง จากนั้นเมื่อไม่จำเป็นต้องใช้เวลานานก็ต้องทำความสะอาด

มีบทความออนไลน์ที่ดีมากเกี่ยวกับวิธีการทำงานดังนั้นฉันจะพูดถึงคำจำกัดความพื้นฐาน

GC เป็นฟังก์ชันที่ใช้ล้างข้อมูลนี้ ในการดำเนินการนี้คือล้างรายการตารางที่ไม่ได้อ้างถึงโดยอ็อบเจ็กต์ที่ใช้งานอยู่ลบอ็อบเจ็กต์อย่างมีประสิทธิภาพมากกว่าการคัดลอกและกระชับหน่วยความจำ มันซับซ้อนกว่านี้เล็กน้อย แต่คุณได้รับความคิด

ปัญหาใหญ่คือบางส่วนกระบวนการนี้มักจะต้องใช้ Java VM ทั้งหมดเพื่อที่จะต้องหยุดชั่วคราวเพื่อให้เกิดขึ้นรวมทั้งกระบวนการทั้งหมดนี้มีตัวประมวลผลและแบนด์วิธหน่วยความจำมาก ตัวเลือกต่างๆของ GC และตัวเลือกการปรับแต่งสำหรับแต่ละตัวเลือกได้รับการออกแบบมาเพื่อสร้างความสมดุลให้กับปัญหาต่างๆเหล่านี้กับกระบวนการ GC ทั้งหมด


0

Garbage Collection ใน Java (และภาษา / แพลตฟอร์มอื่น ๆ ด้วย) เป็นวิธีสำหรับ java run-time environment (JRE) เพื่อนำหน่วยความจำกลับมาใช้ใหม่จากอ็อบเจ็กต์ java ที่ไม่จำเป็นอีกต่อไป อย่างง่ายเมื่อ JRE เริ่มทำงานระบบจะขอหน่วยความจำจำนวนหนึ่งจากระบบปฏิบัติการ (O / S) เมื่อ JRE รันแอปพลิเคชันของคุณจะใช้หน่วยความจำนั้น เมื่อแอปพลิเคชันของคุณเสร็จสิ้นโดยใช้หน่วยความจำนั้น "Garbage Collector" ของ JRE จะมาพร้อมและเรียกคืนหน่วยความจำนั้นเพื่อใช้ในส่วนต่างๆของแอปพลิเคชันที่มีอยู่ของคุณ "Garbage Collector" ของ JRE เป็นงานเบื้องหลังที่ทำงานอยู่ตลอดเวลาและพยายามเลือกเวลาที่ระบบไม่ได้ใช้งานเพื่อดำเนินการกับขยะ

การเปรียบเทียบในโลกแห่งความเป็นจริงก็คือคนทิ้งขยะที่มาที่บ้านของคุณและรับขยะรีไซเคิลของคุณ ... ในที่สุดก็นำกลับมาใช้ใหม่ในรูปแบบอื่นด้วยตัวคุณเองและ / หรือคนอื่น ๆ


0

ตัวเก็บขยะสามารถดูได้ในฐานะผู้จัดการการนับอ้างอิง หากออบเจ็กต์ถูกสร้างขึ้นและการอ้างอิงถูกเก็บไว้ในตัวแปรจำนวนการอ้างอิงจะเพิ่มขึ้นทีละหนึ่ง ในระหว่างการดำเนินการหากตัวแปรนั้นถูกกำหนดด้วย NULL จำนวนอ้างอิงสำหรับวัตถุนั้นจะลดลง ดังนั้นจำนวนการอ้างอิงปัจจุบันสำหรับอ็อบเจ็กต์จึงเป็น 0 ตอนนี้เมื่อเรียกใช้ Garbage Collector มันจะตรวจหาอ็อบเจ็กต์ที่อ้างอิงจำนวน 0 และปลดปล่อยทรัพยากรที่จัดสรรให้

การเรียกเก็บขยะถูกควบคุมโดยนโยบายการรวบรวมขยะ

คุณสามารถรับข้อมูลได้ที่นี่ http://www.oracle.com/technetwork/java/gc-tuning-5-138395.html


1
การนับการอ้างอิงเป็นวิธีหนึ่งที่ยุ่งยากในการนำ GC ไปใช้ ฉันไม่คิดว่าการติดตั้ง JVM หลัก ๆ จะใช้สิ่งนี้
NullUserException

0

คนเก็บขยะเป็นส่วนประกอบของ jvm

ใช้ในการเก็บขยะเมื่อ cpu ได้รับฟรี

ขยะในที่นี้หมายถึงวัตถุที่ไม่ได้ใช้ซึ่งทำงานในพื้นหลังของโปรแกรมหลัก

เพื่อตรวจสอบสถานะของโปรแกรมหลัก


0

การรวบรวมขยะอัตโนมัติเป็นกระบวนการในการดูหน่วยความจำฮีปโดยระบุว่าวัตถุใดถูกใช้งานและไม่ได้ใช้งานและลบวัตถุที่ไม่ได้ใช้ วัตถุที่ใช้งานอยู่หรือวัตถุอ้างอิงหมายความว่าบางส่วนของโปรแกรมของคุณยังคงรักษาตัวชี้ไปยังวัตถุนั้น อ็อบเจ็กต์ที่ไม่ได้ใช้หรืออ็อบเจ็กต์ที่ไม่ได้อ้างอิงจะไม่ถูกอ้างอิงโดยส่วนใด ๆ ของโปรแกรมของคุณอีกต่อไป ดังนั้นหน่วยความจำที่ใช้โดยอ็อบเจ็กต์ที่ไม่ได้อ้างถึงสามารถเรียกคืนได้

ในภาษาการเขียนโปรแกรมเช่น C การจัดสรรและยกเลิกการจัดสรรหน่วยความจำเป็นกระบวนการที่ต้องทำเอง ใน Java กระบวนการกำจัดการจัดสรรหน่วยความจำจะถูกจัดการโดยอัตโนมัติโดยตัวรวบรวมขยะ โปรดตรวจสอบลิงก์เพื่อความเข้าใจที่ดีขึ้น http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html


0

การรวบรวมขยะหมายถึงกระบวนการเพิ่มหน่วยความจำบนฮีปโดยอัตโนมัติโดยการลบอ็อบเจ็กต์ที่ไม่สามารถเข้าถึงได้ในโปรแกรมของคุณอีกต่อไป ฮีปเป็นหน่วยความจำที่เรียกว่าที่เก็บฟรีซึ่งแสดงถึงหน่วยความจำที่ไม่ได้ใช้งานขนาดใหญ่ที่จัดสรรให้กับแอปพลิเคชัน Java ของคุณ


1
อย่าใช้การจัดรูปแบบใบเสนอราคาสำหรับข้อความที่ไม่ได้ยกมาและหากมีการยกมาคุณจำเป็นต้องอ้างอิงแหล่งที่มา
Marquis of Lorne

0

หลักการพื้นฐานของการรวบรวมขยะคือการค้นหาวัตถุข้อมูลในโปรแกรมที่ไม่สามารถเข้าถึงได้ในอนาคตและเรียกคืนทรัพยากรที่ใช้โดยวัตถุเหล่านั้น https://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29

ข้อดี

1) บันทึกจากจุดบกพร่องซึ่งเกิดขึ้นเมื่อหน่วยความจำว่างในขณะที่ยังมีตัวชี้อยู่และหนึ่งในตัวชี้เหล่านั้นจะถูกยกเลิกการอ้างอิง https://en.wikipedia.org/wiki/Dangling_pointer

2) จุดบกพร่องฟรีสองเท่าซึ่งเกิดขึ้นเมื่อโปรแกรมพยายามเพิ่มพื้นที่หน่วยความจำที่ได้รับการปลดปล่อยไปแล้วและอาจได้รับการจัดสรรอีกครั้งแล้ว

3) ป้องกันการรั่วไหลของหน่วยความจำบางประเภทซึ่งโปรแกรมไม่สามารถปลดปล่อยหน่วยความจำที่ถูกครอบครองโดยวัตถุที่ไม่สามารถเข้าถึงได้ซึ่งอาจทำให้หน่วยความจำหมดลง

ข้อเสีย

1) การใช้ทรัพยากรเพิ่มเติมผลกระทบด้านประสิทธิภาพการหยุดชะงักที่เป็นไปได้ในการดำเนินการโปรแกรมและความเข้ากันไม่ได้กับการจัดการทรัพยากรด้วยตนเอง การรวบรวมขยะใช้ทรัพยากรในการประมวลผลในการตัดสินใจว่าหน่วยความจำใดที่จะว่างแม้ว่าโปรแกรมเมอร์อาจทราบข้อมูลนี้แล้วก็ตาม

2) ช่วงเวลาที่เก็บขยะจริงอาจไม่สามารถคาดเดาได้ส่งผลให้แผงลอย (หยุดชั่วคราวเพื่อเปลี่ยน / หน่วยความจำว่าง) กระจัดกระจายไปทั่วเซสชัน แผงลอยที่คาดเดาไม่ได้อาจไม่สามารถยอมรับได้ในสภาพแวดล้อมแบบเรียลไทม์ในการประมวลผลธุรกรรมหรือในโปรแกรมแบบโต้ตอบ


บทช่วยสอน Oracle http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html

การรวบรวมขยะเป็นกระบวนการที่ระบุว่าวัตถุใดถูกใช้งานและไม่ได้ใช้งานและลบวัตถุที่ไม่ได้ใช้

ในภาษาโปรแกรมเช่น C, C ++ การจัดสรรและการเพิ่มหน่วยความจำเป็นกระบวนการที่ต้องทำด้วยตนเอง

int * array = new int[size];
processArray(array); //do some work.
delete array; //Free memory

ขั้นตอนแรกในกระบวนการนี้เรียกว่าการทำเครื่องหมาย นี่คือที่ที่ตัวรวบรวมขยะระบุว่าหน่วยความจำใดถูกใช้งานและไม่ได้ใช้งาน

ขั้นตอนที่ 2a. การลบแบบปกติจะลบอ็อบเจ็กต์ที่ไม่ได้อ้างถึงออกจากอ็อบเจ็กต์และพอยน์เตอร์ที่อ้างอิงไปยังพื้นที่ว่าง

เพื่อปรับปรุงประสิทธิภาพเราต้องการลบอ็อบเจ็กต์ที่ไม่ได้อ้างอิงและบีบอัดอ็อบเจ็กต์ที่อ้างอิงที่เหลือ เราต้องการเก็บวัตถุที่อ้างอิงไว้ด้วยกันดังนั้นการจัดสรรหน่วยความจำใหม่จะเร็วกว่า

ตามที่ระบุไว้ก่อนหน้านี้การทำเครื่องหมายและกระชับวัตถุทั้งหมดใน JVM นั้นไม่มีประสิทธิภาพ เมื่อมีการจัดสรรวัตถุมากขึ้นเรื่อย ๆ รายการของออบเจ็กต์ก็จะเพิ่มขึ้นเรื่อย ๆ ซึ่งนำไปสู่เวลาในการรวบรวมขยะที่ยาวนานขึ้นและยาวนานขึ้น

อ่านบทแนะนำนี้ต่อไปแล้วคุณจะรู้ว่า GC รับมือกับความท้าทายนี้อย่างไร

ในระยะสั้นมีสามพื้นที่ของฮีปYoungGenerationสำหรับวัตถุอายุสั้นOldGenerationสำหรับวัตถุที่มีระยะเวลานานและPermanentGenerationสำหรับวัตถุที่อยู่ในช่วงอายุการใช้งานตัวอย่างเช่นคลาสไลบรารี


0

เนื่องจากอ็อบเจ็กต์ใหม่จัดสรรแบบไดนามิกโดยตัวดำเนินการใหม่คุณสามารถถามได้ว่าอ็อบเจ็กต์เหล่านี้ถูกทำลายอย่างไรและมีการปลดปล่อยหน่วยความจำที่ไม่ว่างอย่างไร ในภาษาอื่น ๆ เช่น C ++ คุณต้องปล่อยวัตถุที่จัดสรรด้วยตนเองแบบไดนามิกโดยตัวดำเนินการลบ Java มีแนวทางที่แตกต่างกัน จะจัดการการจัดสรรตำแหน่งโดยอัตโนมัติ เทคนิคที่เป็นที่รู้จักกันเก็บขยะ

การทำงานเช่นนี้: เมื่อไม่มีการอ้างอิงถึงอ็อบเจ็กต์สมมติว่าอ็อบเจ็กต์นี้ไม่ต้องการอีกต่อไปและคุณสามารถดึงข้อมูลหน่วยความจำที่ครอบครองโดยอ็อบเจ็กต์ได้ ไม่จำเป็นต้องทำลายวัตถุอย่างชัดเจนเช่นเดียวกับใน C ++ การรวบรวมขยะเกิดขึ้นเป็นระยะ ๆ ระหว่างการเรียกใช้โปรแกรม มันไม่ได้เกิดขึ้นเพียงเพราะมีวัตถุอย่างน้อยหนึ่งชิ้นที่ไม่ได้ใช้แล้ว นอกจากนี้การใช้งานรันไทม์ Java หลายวิธียังมีแนวทางในการรวบรวมขยะที่แตกต่างกัน แต่โปรแกรมเมอร์ส่วนใหญ่ไม่ต้องกังวลเรื่องนี้เมื่อเขียนโปรแกรม


-2

การรวบรวมขยะอัตโนมัติเป็นกระบวนการที่ JVM กำจัดหรือเก็บจุดข้อมูลบางจุดไว้ในหน่วยความจำเพื่อเพิ่มพื้นที่ว่างสำหรับโปรแกรมที่กำลังทำงานอยู่ในที่สุด หน่วยความจำจะถูกส่งไปยังหน่วยความจำฮีปเป็นครั้งแรกซึ่งเป็นจุดที่ตัวรวบรวมขยะ (GC) ทำงานจากนั้นจึงตัดสินใจที่จะยกเลิกหรือเก็บไว้ Java ถือว่าโปรแกรมเมอร์ไม่สามารถเชื่อถือได้เสมอไปดังนั้นจึงยุติรายการที่คิดว่าไม่ต้องการ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.