การกำหนดอ็อบเจ็กต์เป็น null ใน Java ส่งผลต่อการรวบรวมขยะหรือไม่


85

การกำหนดการอ้างอิงอ็อบเจ็กต์ที่ไม่ได้ใช้nullใน Java ช่วยปรับปรุงกระบวนการรวบรวมขยะด้วยวิธีใด ๆ ที่วัดผลได้หรือไม่?

ประสบการณ์ของฉันกับ Java (และ C #) สอนฉันว่ามักจะต่อต้านการพยายามและเอาชนะเครื่องเสมือนหรือคอมไพเลอร์ JIT แต่ฉันเคยเห็นเพื่อนร่วมงานใช้วิธีนี้และฉันอยากรู้ว่านี่เป็นแนวทางปฏิบัติที่ดีในการเลือกหรือไม่ หรือหนึ่งในความเชื่อโชคลางการเขียนโปรแกรมวูดู?

คำตอบ:


66

โดยปกติแล้วไม่

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

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

ตัวอย่างเช่นรหัสนี้จาก ArrayList:

public E remove(int index) {
    RangeCheck(index);

    modCount++;
    E oldValue = (E) elementData[index];

    int numMoved = size - index - 1;
    if (numMoved > 0)
         System.arraycopy(elementData, index+1, elementData, index,
             numMoved);
    elementData[--size] = null; // Let gc do its work

    return oldValue;
}

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

ทั้งสอง:

void foo() {
   Object o = new Object();
   /// do stuff with o
}

และ:

void foo() {
   Object o = new Object();
   /// do stuff with o
   o = null;
}

เทียบเท่ากับการทำงาน


7
คุณอาจต้องการใช้การอ้างอิงที่เป็นโมฆะภายในเมธอดที่อาจใช้หน่วยความจำจำนวนมากหรือใช้เวลาดำเนินการนานหรือในโค้ดในแอปพลิเคชัน Swing ที่อาจทำงานเป็นเวลานาน ในวิธีการสั้น ๆ หรือวัตถุที่มีอายุสั้นมันไม่คุ้มกับรหัสที่ทำให้สับสน
John Gardner

1
ใช่หรือไม่เมื่อเราว่างวัตถุตัวเก็บขยะจะรวบรวมวัตถุนั้นทันที ??
มูฮัมหมัดบาบาร์

1
ไม่ตัวรวบรวมขยะจะถูกเรียกใช้งานเป็นระยะเพื่อดูว่ามีวัตถุใดบ้างที่ไม่มีตัวแปรอ้างอิงชี้ไปที่ เมื่อคุณตั้งค่าเป็นโมฆะแล้วเรียกใช้งานSystem.gc()นั้นจะถูกลบออก (หากไม่มีการอ้างอิงอื่น ๆ ที่ชี้ไปที่วัตถุนั้น)
JavaTechnical

2
@JavaTechnical ตามที่ฉันทราบไม่มีการรับประกันว่าการเรียกเก็บขยะ System.gc () จะเริ่มขึ้น
Jack

12

จากประสบการณ์ของฉันบ่อยครั้งที่ผู้คนไม่สนใจการอ้างอิงด้วยความหวาดระแวงไม่ใช่จากความจำเป็น คำแนะนำโดยย่อมีดังนี้

  1. หากออบเจ็กต์ A อ้างอิงอ็อบเจ็กต์ B และคุณไม่ต้องการการอ้างอิงนี้อีกต่อไปและอ็อบเจ็กต์ A ไม่มีสิทธิ์ในการรวบรวมขยะคุณควรลบฟิลด์อย่างชัดเจน ไม่จำเป็นต้องโมฆะออกจากเขตข้อมูลหากวัตถุที่ปิดล้อมกำลังได้รับขยะที่รวบรวมอยู่ การลบฟิลด์ในเมธอด dispose () แทบจะไม่มีประโยชน์เลย

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

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


11

บทความที่ดีคือวันนี้การเข้ารหัสสยองขวัญ

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

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

ปัญหาอาจซับซ้อนด้วยการเพิ่มประสิทธิภาพโค้ดหากคุณไม่เคยใช้ตัวแปรหลังจากที่คุณตั้งค่าเป็น null การเพิ่มประสิทธิภาพที่ปลอดภัยจะเป็นการลบบรรทัดที่กำหนดค่าเป็น null (คำสั่งน้อยกว่าหนึ่งคำสั่งเพื่อดำเนินการ) ดังนั้นคุณอาจไม่ได้รับการปรับปรุงใด ๆ

โดยสรุปแล้วใช่มันสามารถช่วยได้ แต่จะไม่สามารถกำหนดได้



จุดดีเกี่ยวกับการเพิ่มประสิทธิภาพที่ปลอดภัยที่ลบบรรทัดการตั้งค่าการอ้างอิงเป็นโมฆะ
asgs

8

อย่างน้อยที่สุดใน java ไม่ใช่การเขียนโปรแกรมวูดูเลย เมื่อคุณสร้างวัตถุใน java โดยใช้ไฟล์

Foo bar = new Foo();

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

bar = null ;

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


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

2
ดี. ตอนนี้สำหรับแบบทดสอบป๊อปสร้างตัวอย่างของโค้ดที่ไม่เพียงพอ คำแนะนำ: มีอยู่จริง
Charlie Martin

7

มันขึ้นอยู่กับ.

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

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

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


6

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

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

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

{
  int l;
  {  // <- here
    String bigThing = ....;
    l = bigThing.length();
  }  // <- and here
}

สิ่งนี้ช่วยให้สามารถเก็บขยะ bigThing ได้ทันทีหลังจากออกจากวงเล็บปีกกาที่ซ้อนกัน


ทางเลือกที่ดี วิธีนี้หลีกเลี่ยงการตั้งค่าตัวแปรเป็น null อย่างชัดเจนและ lint เตือน IDE บางตัวจะแสดงเกี่ยวกับการกำหนดค่า null นั้นไม่ได้ใช้
jk7

5
public class JavaMemory {
    private final int dataSize = (int) (Runtime.getRuntime().maxMemory() * 0.6);

    public void f() {
        {
            byte[] data = new byte[dataSize];
            //data = null;
        }

        byte[] data2 = new byte[dataSize];
    }

    public static void main(String[] args) {

        JavaMemory jmp = new JavaMemory();
        jmp.f();

    }

}

OutOfMemoryErrorโปรแกรมดังกล่าวข้างต้นพ่น หากคุณdata = null;ไม่แสดงความคิดเห็นOutOfMemoryErrorจะได้รับการแก้ไข เป็นแนวทางปฏิบัติที่ดีเสมอในการตั้งค่าตัวแปรที่ไม่ได้ใช้เป็นค่าว่าง


นั่นคือ imo การโจมตีที่มั่นคงในโลกของการโต้แย้งของมนุษย์ฟาง เพียงเพราะคุณสามารถสร้างสถานการณ์ที่การตั้งค่าตัวแปรเป็นค่าว่างจะช่วยแก้ปัญหาในกรณีนั้น ๆ ได้ (และฉันไม่มั่นใจว่าคุณทำเช่นนั้นแล้ว) ไม่ได้หมายความว่าการตั้งค่าเป็นโมฆะเป็นความคิดที่ดีในทุกกรณี การเพิ่มโค้ดเพื่อตั้งค่าตัวแปรทุกตัวที่คุณไม่ได้ใช้อีกต่อไปให้เป็นโมฆะแม้ว่าพวกเขาจะออกนอกขอบเขตหลังจากนั้นไม่นานก็เพิ่มลงในโค้ดขยายและทำให้โค้ดไม่สามารถบำรุงรักษาได้
RHSeeger

เหตุใดอาร์เรย์ไบต์ [] จึงไม่ถูกรวบรวมในขณะที่ข้อมูลตัวแปรอยู่นอกขอบเขต
Grav

2
@Grav: การออกนอกขอบเขตไม่รับประกันว่าคนเก็บขยะจะรวบรวมวัตถุในพื้นที่ อย่างไรก็ตามการตั้งค่าเป็น null จะป้องกันข้อยกเว้น OutOfMemory เนื่องจากคุณได้รับการรับรองว่า GC จะทำงานก่อนที่จะใช้ข้อยกเว้น OutOfMemory และหากตั้งค่าวัตถุเป็นโมฆะก็จะสามารถรวบรวมได้
Stefanos T.


4

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

จึงขึ้นอยู่กับสิ่งที่คุณทำ ...


2

ใช่.

จาก "The Pragmatic Programmer" p.292:

โดยการตั้งค่าการอ้างอิงเป็น NULL คุณจะลดจำนวนตัวชี้ไปยังวัตถุทีละหนึ่ง ... (ซึ่งจะช่วยให้ตัวรวบรวมขยะลบออกได้)


ฉันเดาว่าสิ่งนี้ใช้ได้เฉพาะกับการนับอ้างอิงเท่านั้น ใช้งานอยู่หรืออย่างอื่นด้วย?
NRJ

3
คำแนะนำนี้ล้าสมัยสำหรับคนเก็บขยะสมัยใหม่ และการนับการอ้างอิง GC มีปัญหาสำคัญเช่นการอ้างอิงแบบวงกลม
Lawrence Dol

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

1

ฉันถือว่า OP อ้างถึงสิ่งต่างๆเช่นนี้:

private void Blah()
{
    MyObj a;
    MyObj b;

    try {
        a = new MyObj();
        b = new MyObj;

        // do real work
    } finally {
        a = null;
        b = null;
    }
}

ในกรณีนี้ VM จะไม่ทำเครื่องหมายเป็น GC ทันทีที่ออกจากขอบเขตใช่หรือไม่

หรือจากมุมมองอื่นการตั้งค่ารายการให้เป็นโมฆะอย่างชัดเจนทำให้พวกเขาได้รับ GC ก่อนที่พวกเขาจะทำหากพวกเขาออกนอกขอบเขต? ถ้าเป็นเช่นนั้น VM อาจใช้เวลาในการ GC 'กับวัตถุเมื่อไม่จำเป็นต้องใช้หน่วยความจำซึ่งจะทำให้ประสิทธิภาพการใช้งาน CPU แย่ลงอย่างชาญฉลาดเนื่องจาก GC จะเร็วกว่า


เวลาที่ GC ทำงานไม่ได้ถูกกำหนด ฉันไม่เชื่อว่าการตั้งค่าวัตถุให้nullมีอิทธิพลต่อพฤติกรรม GC เลย
harto

0

" มันขึ้นอยู่กับ "

ฉันไม่รู้เกี่ยวกับ Java แต่ใน. net (C #, VB.net ... ) มักไม่จำเป็นต้องกำหนดค่าว่างเมื่อคุณไม่ต้องการวัตถุอีกต่อไป

อย่างไรก็ตามโปรดทราบว่า "โดยปกติไม่จำเป็น"

ด้วยการวิเคราะห์โค้ดของคุณคอมไพเลอร์. net จะทำการประเมินค่าอายุการใช้งานของตัวแปรได้ดี ... เพื่อบอกได้อย่างแม่นยำว่าเมื่อใดที่ไม่ได้ใช้ออบเจ็กต์อีกต่อไป ดังนั้นถ้าคุณเขียน obj = null มันอาจดูเหมือนว่า obj ยังคงถูกใช้อยู่ ... ในกรณีนี้มันเป็นการต่อต้านที่จะกำหนด null

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

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

หากเป็น. net code ที่คุณพยายามปรับให้เหมาะสมจากนั้นประสบการณ์ของฉันก็คือการดูแลอย่างดีด้วยวิธี Dispose and Finalize นั้นมีประโยชน์มากกว่าการรบกวนเกี่ยวกับ null

การอ้างอิงบางส่วนในหัวข้อ:

http://blogs.msdn.com/csharpfaq/archive/2004/03/26/97229.aspx

http://weblogs.asp.net/pwilson/archive/2004/02/20/77422.aspx


0

แม้ว่าการลบล้างข้อมูลอ้างอิงจะมีประสิทธิภาพมากกว่าเล็กน้อย แต่มันจะคุ้มค่ากับความน่าเกลียดที่ต้องเพิ่มรหัสของคุณด้วยค่า null ที่น่าเกลียดเหล่านี้หรือไม่? พวกเขามี แต่จะยุ่งเหยิงและปิดบังรหัสเจตนาที่มีอยู่

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


0

ในการดำเนินการโปรแกรมของคุณในอนาคตค่าของสมาชิกข้อมูลบางส่วนจะถูกใช้กับคอมพิวเตอร์เอาต์พุตที่มองเห็นได้ภายนอกของโปรแกรม อื่น ๆ อาจใช้หรือไม่ก็ได้ขึ้นอยู่กับอินพุตในอนาคต (และเป็นไปไม่ได้ที่จะทำนาย) ของโปรแกรม อาจมีการรับประกันว่าสมาชิกข้อมูลอื่น ๆ จะไม่ถูกนำไปใช้ ทรัพยากรทั้งหมดรวมถึงหน่วยความจำที่จัดสรรให้กับข้อมูลที่ไม่ได้ใช้เหล่านั้นจะสูญเปล่า หน้าที่ของคนเก็บขยะ (GC) คือกำจัดหน่วยความจำที่สิ้นเปลืองนั้น มันจะเป็นหายนะสำหรับ GC ที่จะกำจัดบางสิ่งที่จำเป็นออกไปดังนั้นอัลกอริทึมที่ใช้อาจเป็นแบบอนุรักษ์นิยมโดยคงไว้มากกว่าขั้นต่ำที่เข้มงวด อาจใช้การเพิ่มประสิทธิภาพฮิวริสติกเพื่อปรับปรุงความเร็วโดยเสียค่าใช้จ่ายในการรักษาบางรายการที่ไม่จำเป็นจริง ๆ มีอัลกอริทึมที่เป็นไปได้มากมายที่ GC อาจใช้ ดังนั้นจึงเป็นไปได้ว่าการเปลี่ยนแปลงที่คุณทำกับโปรแกรมของคุณ และไม่ส่งผลกระทบต่อความถูกต้องของโปรแกรมของคุณอย่างไรก็ตามอาจส่งผลกระทบต่อการทำงานของ GC ทั้งทำให้ทำงานได้เร็วขึ้นเพื่อทำงานเดียวกันหรือระบุรายการที่ไม่ได้ใช้เร็วขึ้น ดังนั้นการเปลี่ยนแปลงประเภทนี้การตั้งค่าการอ้างอิงวัตถุที่ผิดปกติเป็นnull, ในทางทฤษฎีจะไม่เสมอวูดู

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


0

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

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

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

เพื่อหลีกเลี่ยงการเลือกที่รักมักที่ชังคุณควรลบการอ้างอิงจากวัตถุที่ควรจะลบออกไป คุณสามารถเห็นเทคนิคนี้ที่ใช้ในคลาส JDK: LinkedListและLinkedHashMap

private E unlinkFirst(Node<E> f) {
    final E element = f.item;
    final Node<E> next = f.next;
    f.item = null;
    f.next = null; // help GC
    // ...
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.