الحياة في الخط السريع



في أول سلسلة على GC ، قدمت جامع القمامة D وميزات اللغة التي تستخدمه. نقطتان رئيسيتان حاولت نقلهما:



  1. يعمل GC فقط عندما تطلب تخصيص ذاكرة . على عكس المفاهيم الخاطئة الشائعة ، لا يمكن لـ D language GC ببساطة إيقاف واستنساخ لعبة Minecraft في منتصف حلقة اللعبة. يتم تشغيله فقط عند طلب الذاكرة من خلاله وفقط عند الحاجة.



  2. يمكن لاستراتيجيات تخصيص الذاكرة على غرار C و C ++ البسيطة تقليل الحمل على GC . لا تخصص ذاكرة داخل الحلقات - بدلاً من ذلك ، قم بتخصيص أكبر عدد ممكن من الموارد مسبقًا أو استخدم المكدس. تقليل العدد الإجمالي لتخصيصات الذاكرة من خلال GC. تعمل هذه الإستراتيجيات بفضل # 1. يمكن للمطور تحديد وقت تشغيل مجموعة القمامة عن طريق استخدام تخصيص كومة الذاكرة المؤقتة المُدار بواسطة GC بذكاء.





تعتبر الاستراتيجيات من النقطة رقم 2 مناسبة للتعليمات البرمجية التي يكتبها المبرمج بنفسه ، ولكنها ليست مفيدة بشكل خاص عندما يتعلق الأمر بمكتبات الجهات الخارجية. في هذه الحالات ، باستخدام آليات اللغة D ووقت تشغيلها ، يمكنك ضمان عدم حدوث تخصيص للذاكرة في النقاط الحرجة في التعليمات البرمجية. هناك أيضًا خيارات سطر الأوامر للمساعدة في التأكد من أن GC لا يعترض طريقك.



دعونا نتخيل أنك تكتب برنامجًا في D ولسبب أو لآخر قررت التخلص من جمع القمامة تمامًا. لديك حلان واضحان



حبوب الجشع



الحل الأول هو الاتصال GC.disableعندما يبدأ البرنامج. سيظل تخصيص الذاكرة عبر GC يعمل ، ولكن سيتوقف جمع القمامة. جميع جمع القمامة ، بما في ذلك ما قد حدث في خيوط أخرى.



void main() {
    import core.memory;
    import std.stdio;
    GC.disable;
    writeln("Goodbye, GC!");
}


انتاج:



Goodbye, GC!


, , GC, , . , , , . , - . :



, , .

, . , - , . GC.enable GC.collect. , C C++.





, @nogc. main, .



@nogc
void main() { ... }


GC. @nogc, main, , . « ».



, GC.disable. .



@nogc
void main() {
    import std.stdio;
    writeln("GC be gone!");
}


:



Error: @nogc function 'D main' cannot call non-@nogc function 'std.stdio.writeln!string.writeln'
(: @nogc- 'D main'    -@nogc– 'std.stdio.writeln!string.writeln')


@nogc , . . @nogc, , , @nogc. , writeln .



:



@nogc 
void main() {
    auto ints = new int[](100);
}


:



Error: cannot use 'new' in @nogc function 'D main'
(:   'new'  @nogc- 'D main')


@nogc- , GC ( ). . , , GC . , , @nogc, .



, @nogc , . , , - ( ). — . :



throw new Exception("Blah");


- , new, @nogc- . , , , - , … , . D , , throw new Exception GC, .



, @nogc- . (. .)

@nogc main — , .



, : @nogc main GC . D . main, — . @nogc, , , GC @nogc-. , @nogc, main, , main , , GC.





. , D, GC . , GC — . , , D: GC . , , .



, , , GC. @nogc / API core.memory.GC . @nogc main, , GC. GC.disable . , GC.enable. , GC (, ), GC.collect.



, , , . API core.memory.GC GC . D.



( !) D --DRT-gcopt=profile:1, . GC, , .



: gcstat.d .



void main() {
    import std.stdio;
    int[] ints;
    foreach(i; 0 .. 20) {
        ints ~= i;
    }
    writeln(ints);
}


GC:



dmd gcstat.d
gcstat --DRT-gcopt=profile:1
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
        Number of collections:  1
        Total GC prep time:  0 milliseconds
        Total mark time:  0 milliseconds
        Total sweep time:  0 milliseconds
        Total page recovery time:  0 milliseconds
        Max Pause Time:  0 milliseconds
        Grand total GC time:  0 milliseconds
GC summary:    1 MB,    1 GC    0 ms, Pauses    0 ms <    0 ms


, , , . D GC , ( ) . , , D , GC - ( ).



DMD -vgc, GC — , , ~=.



: inner.d.



void printInts(int[] delegate() dg)
{
    import std.stdio;
    foreach(i; dg()) writeln(i);
} 

void main() {
    int[] ints;
    auto makeInts() {
        foreach(i; 0 .. 20) {
            ints ~= i;
        }
        return ints;
    }

    printInts(&makeInts);
}


makeInts — . , , / ( static, delegate function). .



-vgc:



dmd -vgc inner.d
inner.d(11): vgc: operator ~= may cause GC allocation
inner.d(7): vgc: using closure causes GC allocation

(inner.d(11): vgc:  ~=      GC)
(inner.d(7): vgc:        GC)


, , ints, ( — - delegate). ints makeInts . , - . printInts :



void printInts(scope int[] delegate() dg)


scope , . , dg . , . . , , .





, GC D , Java C#, . , D , Java, . , D. , Java, GC , .



, , , , . D № 2 , @nogc core.memory.GC , . , , , .



, D. , Phobos — D — @nogc. , , .



في المقالات المستقبلية ، سوف ننظر في كيفية تخصيص الذاكرة دون اللجوء إلى GC ، واستخدامها بالتوازي مع الذاكرة من GC ، بدلاً من استبدال @nogcميزات اللغة غير المتوفرة في التعليمات البرمجية ، وأكثر من ذلك بكثير.



بفضل Vladimir Panteleev و Guillaume Piolat و Steven Schveighoffer لتعليقاتهم القيمة على مسودة هذه المقالة.




All Articles