الفرق بين المراجعتين ل"Ruby/GC"

من موسوعة حسوب
اذهب إلى التنقل اذهب إلى البحث
(أنشأ الصفحة ب' <noinclude>{{DISPLAYTITLE: الوحدة GC في روبي}}</noinclude> = الوحدة GC = توفر الوحدة GC واجهة لتحديد ومسح آلية جمع ا...')
 
سطر 1: سطر 1:
<noinclude>{{DISPLAYTITLE: الوحدة GC في روبي}}</noinclude>
 
 
= الوحدة GC =
 
 
توفر الوحدة GC واجهة لتحديد ومسح آلية جمع البيانات المهملة في روبي.
 
توفر الوحدة GC واجهة لتحديد ومسح آلية جمع البيانات المهملة في روبي.
  
تتوفر أيضًا بعض التوابع الأساسية من خلال الوحدة ObjectSpace.
+
تتوفر أيضًا بعض التوابع الأساسية من خلال الوحدة [[Ruby/ObjectSpace|ObjectSpace]].
  
ويمكن الحصول على المزيد من المعلومات حول تشغيل GC من خلال GC::Profiler.
+
ويمكن الحصول على المزيد من المعلومات حول تشغيل GC من خلال [[Ruby/GC::Profiler|GC::Profiler]].
  
=== الثوابت === 
+
=== الثوابت ===
 +
<code>INTERNAL_CONSTANTS</code>
  
INTERNAL_CONSTANTS
+
<code>OPTS</code>
 +
===توابع الصنف العام===
  
OPTS
+
=== <code>add_stress_to_class(*args)‎</code> ===
 +
أمثلة<syntaxhighlight lang="ruby">
 +
    static VALUE
 +
rb_gcdebug_add_stress_to_class(int argc, VALUE *argv, VALUE self)
 +
{
 +
    rb_objspace_t *objspace = &rb_objspace;
  
=== توابع الصنف العام ===
+
    if (!stress_to_class) {
add_stress_to_class(*args)
+
        stress_to_class = rb_ary_tmp_new(argc);
 
+
    }
count → Integer
+
    rb_ary_cat(stress_to_class, argv, argc);
 +
    return self;
 +
}
 +
         
 +
</syntaxhighlight>
  
 +
=== <code>count → Integer</code> ===
 
عدد مرات حدوث GC.
 
عدد مرات حدوث GC.
  
 
إعادة عدد مرات حدوث GC منذ بدء العملية.
 
إعادة عدد مرات حدوث GC منذ بدء العملية.
  
disable → true or false
+
أمثلة<syntaxhighlight lang="ruby">
 +
              static VALUE
 +
gc_count(VALUE self)
 +
{
 +
    return SIZET2NUM(rb_gc_count());
 +
}
 +
           
 +
</syntaxhighlight>
 +
 
 +
=== <code>disable → true or false</code> ===
 +
تعطيل جمع البيانات المهملة، وإعادة <code>true</code> إذا كان جمع البيانات المهملة مُعطَّلًا بالفعل.<syntaxhighlight lang="ruby">
 +
GC.disable  #=> false
 +
GC.disable  #=> true
 +
</syntaxhighlight>أمثلة<syntaxhighlight lang="ruby">
 +
              VALUE
 +
rb_gc_disable(void)
 +
{
 +
    rb_objspace_t *objspace = &rb_objspace;
 +
    int old = dont_gc;
 +
 
 +
    gc_rest(objspace);
  
تعطيل جمع البيانات المهملة، وإعادة true إذا كان جمع البيانات المهملة مُعطَّلًا بالفعل.
+
    dont_gc = TRUE;
 +
    return old ? Qtrue : Qfalse;
 +
}
 +
   
 +
</syntaxhighlight>
  
 zero? → true أو false
+
=== <code>zero? → true أو false</code> ===
 +
تفعيل جمع البيانات المهملة، وإعادة <code>true</code> إذا كان جمع البيانات المهملة مُعطَّلًا بالفعل.<syntaxhighlight lang="ruby">
 +
GC.disable  #=> false
 +
GC.enable    #=> true
 +
GC.enable    #=> false
  
تفعيل جمع البيانات المهملة، وإعادة true إذا كان جمع البيانات المهملة مُعطَّلًا بالفعل.
+
</syntaxhighlight>أمثلة<syntaxhighlight lang="ruby">
 +
 +
              VALUE
 +
rb_gc_enable(void)
 +
{
 +
    rb_objspace_t *objspace = &rb_objspace;
 +
    int old = dont_gc;
  
 latest_gc_info → {:gc_by=>:newobj}
+
    dont_gc = FALSE;
 +
    return old ? Qtrue : Qfalse;
 +
}
 +
     
 +
</syntaxhighlight>
  
latest_gc_info(hash) hash
+
=== <code>latest_gc_info → {:gc_by=>:newobj}‎</code> ===
  
latest_gc_info(:major_by) → :malloc
+
=== <code>latest_gc_info(hash) → hash</code> ===
  
 +
=== <code>latest_gc_info(:major_by) → :malloc</code> ===
 
إعادة معلومات حول أحدث عملية جمع البيانات المهملة.
 
إعادة معلومات حول أحدث عملية جمع البيانات المهملة.
  
malloc_allocated_size → Integer
+
أمثلة<syntaxhighlight lang="ruby">
 +
 
 +
              static VALUE
 +
gc_latest_gc_info(int argc, VALUE *argv, VALUE self)
 +
{
 +
    rb_objspace_t *objspace = &rb_objspace;
 +
    VALUE arg = Qnil;
 +
 
 +
    if (rb_scan_args(argc, argv, "01", &arg) == 1) {
 +
        if (!SYMBOL_P(arg) && !RB_TYPE_P(arg, T_HASH)) {
 +
            rb_raise(rb_eTypeError, "non-hash or symbol given");
 +
        }
 +
    }
 +
 
 +
    if (arg == Qnil) {
 +
        arg = rb_hash_new();
 +
    }
 +
 
 +
    return gc_info_decode(objspace, arg, 0);
 +
}
 +
         
 +
</syntaxhighlight>
 +
 
 +
=== <code>malloc_allocated_size → Integer</code> ===
 +
إعادة حجم الذاكرة المخصصة من قِبَل <code>malloc()</code>‎.
 +
 
 +
ويتوفر فقط إذا بُنيت روبي مع <code>CALC_EXACT_MALLOC_SIZE</code>.
  
إعادة حجم الذاكرة المخصصة من قِبَل malloc()‎.
+
أمثلة<syntaxhighlight lang="ruby">
  
ويتوفر فقط إذا بُنيت روبي مع CALC_EXACT_MALLOC_SIZE.
+
              static VALUE
 +
gc_malloc_allocated_size(VALUE self)
 +
{
 +
    return UINT2NUM(rb_objspace.malloc_params.allocated_size);
 +
}
 +
</syntaxhighlight><code>malloc_allocations → Integer</code>
  
malloc_allocations → Integer
+
إعادة عدد عمليات مُخصصات <code>malloc()</code>‎.
  
إعادة عدد عمليات مُخصصات malloc()‎.
+
ويتوفر فقط إذا بُنيت روبي مع <code>CALC_EXACT_MALLOC_SIZE</code>.
  
ويتوفر فقط إذا بُنيت روبي مع CALC_EXACT_MALLOC_SIZE.
+
أمثلة<syntaxhighlight lang="ruby">
 +
 +
              static VALUE
 +
gc_malloc_allocations(VALUE self)
 +
{
 +
    return UINT2NUM(rb_objspace.malloc_params.allocations);
 +
}
 +
       
 +
</syntaxhighlight>
  
remove_stress_to_class(*args)‎
+
=== <code>remove_stress_to_class(*args)‎</code> ===
 +
أمثلة<syntaxhighlight lang="ruby">
  
start → nil
+
              static VALUE
 +
rb_gcdebug_remove_stress_to_class(int argc, VALUE *argv, VALUE self)
 +
{
 +
    rb_objspace_t *objspace = &rb_objspace;
 +
    int i;
  
start(full_mark: true, immediate_sweep: true) → nil
+
    if (stress_to_class) {
 +
        for (i = 0; i < argc; ++i) {
 +
            rb_ary_delete_same(stress_to_class, argv[i]);
 +
        }
 +
        if (RARRAY_LEN(stress_to_class) == 0) {
 +
            stress_to_class = 0;
 +
        }
 +
    }
 +
    return Qnil;
 +
}
 +
           
 +
</syntaxhighlight>
  
 +
=== <code>start → nil</code> ===
 +
 +
=== <code>start(full_mark: true, immediate_sweep: true) → nil</code> ===
 
بدء تجميع البيانات المهملة، ما لم تُعطَّل يدويًا.
 
بدء تجميع البيانات المهملة، ما لم تُعطَّل يدويًا.
  
يُحدد هذا التابع بوسائط الكلمات المفتاحية قِيَمَها الافتراضية true:
+
يُحدد هذا التابع بوسائط الكلمات المفتاحية قِيَمَها الافتراضية <code>true</code>:<syntaxhighlight lang="ruby">
 
 
 
def GC.start(full_mark: true, immediate_sweep: true); end
 
def GC.start(full_mark: true, immediate_sweep: true); end
  
يُضبط full_mark بالقيمة false لتنفيذ GC ثانوية. يُضبط immediate_sweep بالقيمة false لتأجيل المسح (استخدام المسح البطيء).
+
</syntaxhighlight>يُضبط <code>full_mark</code> بالقيمة <code>false</code> لتنفيذ GC ثانوية. يُضبط <code>immediate_sweep</code> بالقيمة <code>false</code> لتأجيل المسح (استخدام المسح البطيء).
  
 
ملاحظة: تعتمد وسائط الكلمات المفتاحية هذه على التطبيق والإصدار. وليس من المضمون أن تظل متوافقة في المستقبل، ويمكن تجاهلها إذا كان التطبيق الأساسي لا يدعمها.
 
ملاحظة: تعتمد وسائط الكلمات المفتاحية هذه على التطبيق والإصدار. وليس من المضمون أن تظل متوافقة في المستقبل، ويمكن تجاهلها إذا كان التطبيق الأساسي لا يدعمها.
  
stat → Hash
+
أمثلة<syntaxhighlight lang="ruby">
  
stat(hash) → hash
+
              static VALUE
 +
gc_start_internal(int argc, VALUE *argv, VALUE self)
 +
{
 +
    rb_objspace_t *objspace = &rb_objspace;
 +
    int full_mark = TRUE, immediate_mark = TRUE, immediate_sweep = TRUE;
 +
    VALUE opt = Qnil;
 +
    static ID keyword_ids[3];
  
stat(:key) → Numeric
+
    rb_scan_args(argc, argv, "0:", &opt);
  
 +
    if (!NIL_P(opt)) {
 +
        VALUE kwvals[3];
 +
 +
        if (!keyword_ids[0]) {
 +
            keyword_ids[0] = rb_intern("full_mark");
 +
            keyword_ids[1] = rb_intern("immediate_mark");
 +
            keyword_ids[2] = rb_intern("immediate_sweep");
 +
        }
 +
 +
        rb_get_kwargs(opt, keyword_ids, 0, 3, kwvals);
 +
 +
        if (kwvals[0] != Qundef) full_mark = RTEST(kwvals[0]);
 +
        if (kwvals[1] != Qundef) immediate_mark = RTEST(kwvals[1]);
 +
        if (kwvals[2] != Qundef) immediate_sweep = RTEST(kwvals[2]);
 +
    }
 +
 +
    garbage_collect(objspace, full_mark, immediate_mark, immediate_sweep, GPR_FLAG_METHOD);
 +
    gc_finalize_deferred(objspace);
 +
 +
    return Qnil;
 +
}
 +
       
 +
</syntaxhighlight>
 +
 +
=== <code>stat → Hash</code> ===
 +
 +
=== <code>stat(hash) → hash</code> ===
 +
 +
=== <code>stat(:key) → Numeric</code> ===
 
إعادة تجزئة Hash تحتوي على معلومات حول GC.
 
إعادة تجزئة Hash تحتوي على معلومات حول GC.
  
تتضمن التجزئة معلومات حول الإحصائيات الداخلية حول GC مثل:
+
تتضمن التجزئة معلومات حول الإحصائيات الداخلية حول GC مثل:<syntaxhighlight lang="ruby">
 +
{
 +
    :count=>0,
 +
    :heap_allocated_pages=>24,
 +
    :heap_sorted_length=>24,
 +
    :heap_allocatable_pages=>0,
 +
    :heap_available_slots=>9783,
 +
    :heap_live_slots=>7713,
 +
    :heap_free_slots=>2070,
 +
    :heap_final_slots=>0,
 +
    :heap_marked_slots=>0,
 +
    :heap_eden_pages=>24,
 +
    :heap_tomb_pages=>0,
 +
    :total_allocated_pages=>24,
 +
    :total_freed_pages=>0,
 +
    :total_allocated_objects=>7796,
 +
    :total_freed_objects=>83,
 +
    :malloc_increase_bytes=>2389312,
 +
    :malloc_increase_bytes_limit=>16777216,
 +
    :minor_gc_count=>0,
 +
    :major_gc_count=>0,
 +
    :remembered_wb_unprotected_objects=>0,
 +
    :remembered_wb_unprotected_objects_limit=>0,
 +
    :old_objects=>0,
 +
    :old_objects_limit=>0,
 +
    :oldmalloc_increase_bytes=>2389760,
 +
    :oldmalloc_increase_bytes_limit=>16777216
 +
}
 +
</syntaxhighlight> محتويات التجزئة خاصة بالتطبيق ويمكن تغييرها في المستقبل.
  
 محتويات التجزئة خاصة بالتطبيق ويمكن تغييرها في المستقبل.
+
ومن المتوقع أن يعمل هذا التابع فقط علي روبي C.
  
ومن المتوقع أن يعمل هذا التابع فقط علي روبي C.
+
أمثلة<syntaxhighlight lang="ruby">
 +
 +
              static VALUE
 +
gc_stat(int argc, VALUE *argv, VALUE self)
 +
{
 +
    VALUE arg = Qnil;
 +
 
 +
    if (rb_scan_args(argc, argv, "01", &arg) == 1) {
 +
        if (SYMBOL_P(arg)) {
 +
            size_t value = gc_stat_internal(arg);
 +
            return SIZET2NUM(value);
 +
        }
 +
        else if (!RB_TYPE_P(arg, T_HASH)) {
 +
            rb_raise(rb_eTypeError, "non-hash or symbol given");
 +
        }
 +
    }
  
stress → integer, true or false
+
    if (arg == Qnil) {
 +
        arg = rb_hash_new();
 +
    }
 +
    gc_stat_internal(arg);
 +
    return arg;
 +
}
 +
         
 +
</syntaxhighlight>
  
 +
=== <code>stress → integer, true or false</code> ===
 
إعادة الحالة الحالية لوضع الضغط لـ GC.
 
إعادة الحالة الحالية لوضع الضغط لـ GC.
  
stress = flag → flag
+
أمثلة<syntaxhighlight lang="ruby">
 +
 +
              static VALUE
 +
gc_stress_get(VALUE self)
 +
{
 +
    rb_objspace_t *objspace = &rb_objspace;
 +
    return ruby_gc_stress_mode;
 +
}
 +
</syntaxhighlight>
  
 +
=== <code>stress = flag → flag</code> ===
 
تحديث وضع الضغط لـ GC.
 
تحديث وضع الضغط لـ GC.
  
سطر 93: سطر 293:
 
سيؤدي تفعيل وضع الضغط إلى خفض الأداء، ويُستعمل فقط للتنقيح.
 
سيؤدي تفعيل وضع الضغط إلى خفض الأداء، ويُستعمل فقط للتنقيح.
  
يمكن أن تكون الراية true، أو false، أو عدد صحيح مُجرى على بِتاته العامل OR تبعًا للرايات.
+
يمكن أن تكون الراية <code>true</code>، أو <code>false</code>، أو عدد صحيح مُجرى على بِتاته العامل OR تبعًا للرايات.<syntaxhighlight lang="ruby">
 +
0x01:: no major GC
 +
0x02:: no immediate sweep
 +
0x04:: full mark after malloc/calloc/realloc
 +
</syntaxhighlight>أمثلة<syntaxhighlight lang="ruby">
 +
 +
              static VALUE
 +
gc_stress_set_m(VALUE self, VALUE flag)
 +
{
 +
    rb_objspace_t *objspace = &rb_objspace;
 +
    gc_stress_set(objspace, flag);
 +
    return flag;
 +
}
 +
           
 +
</syntaxhighlight>
 +
 
 +
=== <code>verify_internal_consistency → nil</code> ===
 +
التحقق من الاتساق الداخلي.
 +
 
 +
هذا التابع خاص بالتطبيق. يتحقق هذا التابع الآن من تناسق الأجيال إذا كان <code>RGenGC</code> مدعومًا.
 +
 
 +
أمثلة<syntaxhighlight lang="ruby">
 +
 +
              static VALUE
 +
gc_verify_internal_consistency(VALUE dummy)
 +
{
 +
    rb_objspace_t *objspace = &rb_objspace;
 +
    struct verify_internal_consistency_struct data = {0};
 +
    struct each_obj_args eo_args;
 +
 
 +
    data.objspace = objspace;
 +
    gc_report(5, objspace, "gc_verify_internal_consistency: start\n");
 +
 
 +
    /* check relations */
 +
 
 +
    eo_args.callback = verify_internal_consistency_i;
 +
    eo_args.data = (void *)&data;
 +
    objspace_each_objects((VALUE)&eo_args);
 +
 
 +
    if (data.err_count != 0) {
 +
#if RGENGC_CHECK_MODE >= 5
 +
        objspace->rgengc.error_count = data.err_count;
 +
        gc_marks_check(objspace, NULL, NULL);
 +
        allrefs_dump(objspace);
 +
#endif
 +
        rb_bug("gc_verify_internal_consistency: found internal inconsistency.");
 +
    }
 +
 
 +
    /* check heap_page status */
 +
    gc_verify_heap_pages(objspace);
 +
 
 +
    /* check counters */
  
verify_internal_consistency → nil
+
    if (!is_lazy_sweeping(heap_eden) && !finalizing) {
 +
        if (objspace_live_slots(objspace) != data.live_object_count) {
 +
            fprintf(stderr, "heap_pages_final_slots: %d, objspace->profile.total_freed_objects: %d\n",
 +
                    (int)heap_pages_final_slots, (int)objspace->profile.total_freed_objects);
 +
            rb_bug("inconsistent live slot number: expect %"PRIuSIZE", but %"PRIuSIZE".", objspace_live_slots(objspace), data.live_object_count);
 +
        }
 +
    }
  
التحقق من الاتساق الداخلي.
+
#if USE_RGENGC
 +
    if (!is_marking(objspace)) {
 +
        if (objspace->rgengc.old_objects != data.old_object_count) {
 +
            rb_bug("inconsistent old slot number: expect %"PRIuSIZE", but %"PRIuSIZE".", objspace->rgengc.old_objects, data.old_object_count);
 +
        }
 +
        if (objspace->rgengc.uncollectible_wb_unprotected_objects != data.remembered_shady_count) {
 +
            rb_bug("inconsistent old slot number: expect %"PRIuSIZE", but %"PRIuSIZE".", objspace->rgengc.uncollectible_wb_unprotected_objects, data.remembered_shady_count);
 +
        }
 +
    }
 +
#endif
 +
 
 +
    if (!finalizing) {
 +
        size_t list_count = 0;
 +
 
 +
        {
 +
            VALUE z = heap_pages_deferred_final;
 +
            while (z) {
 +
                list_count++;
 +
                z = RZOMBIE(z)->next;
 +
            }
 +
        }
 +
 
 +
        if (heap_pages_final_slots != data.zombie_object_count ||
 +
            heap_pages_final_slots != list_count) {
 +
 
 +
            rb_bug("inconsistent finalizing object count:\n"
 +
                  "  expect %"PRIuSIZE"\n"
 +
                  "  but    %"PRIuSIZE" zombies\n"
 +
                  "  heap_pages_deferred_final list has %"PRIuSIZE" items.",
 +
                  heap_pages_final_slots,
 +
                  data.zombie_object_count,
 +
                  list_count);
 +
        }
 +
    }
  
هذا التابع خاص بالتطبيق. يتحقق هذا التابع الآن من تناسق الأجيال إذا كان RGenGC مدعومًا.
+
    gc_report(5, objspace, "gc_verify_internal_consistency: OK\n");
  
=== توابع المثيل العام ===
+
    return Qnil;
garbage_collect → nilclick النقر للتبديل المصدر
+
}
 +
       
 +
</syntaxhighlight>
 +
===توابع المثيل العام===
  
وتشمل GC; garbage_collect → nil
+
=== <code>garbage_collect → nil</code> ===
  
garbage_collect(full_mark: true, immediate_sweep: true) → nil
+
=== <code>GC; garbage_collect → nil</code> ===
  
 +
=== <code>garbage_collect(full_mark: true, immediate_sweep: true) → nil</code> ===
 
بدء تجميع البيانات المهملة، ما لم تُعطَّل يدويًا.
 
بدء تجميع البيانات المهملة، ما لم تُعطَّل يدويًا.
  
يُحدد هذا التابع بوسائط الكلمات المفتاحية قِيَمَها الافتراضية true:
+
يُحدد هذا التابع بوسائط الكلمات المفتاحية قِيَمَها الافتراضية <code>true</code>:<syntaxhighlight lang="ruby">
 +
def GC.start(full_mark: true, immediate_sweep: true); end
  
 يُضبط full_mark بالقيمة false لتنفيذ GC ثانوية. يُضبط immediate_sweep بالقيمة false لتأجيل المسح (استخدام المسح البطيء).
+
</syntaxhighlight> يُضبط <code>full_mark</code> بالقيمة <code>false</code> لتنفيذ GC ثانوية. ,يُضبط <code>immediate_sweep</code> بالقيمة <code>false</code> لتأجيل المسح (استخدام المسح البطيء).
  
 
ملاحظة: تعتمد وسائط الكلمات المفتاحية هذه على التطبيق والإصدار. وليس من المضمون أن تكون متوافقة في المستقبل، ويمكن تجاهلها إذا كان التطبيق الأساسي لا يدعمها.
 
ملاحظة: تعتمد وسائط الكلمات المفتاحية هذه على التطبيق والإصدار. وليس من المضمون أن تكون متوافقة في المستقبل، ويمكن تجاهلها إذا كان التطبيق الأساسي لا يدعمها.
  
= مصادر =
+
أمثلة<syntaxhighlight lang="ruby">
* صفحة وحدة GC في توثيق روبي الرسمي.
+
 +
              static VALUE
 +
gc_start_internal(int argc, VALUE *argv, VALUE self)
 +
{
 +
    rb_objspace_t *objspace = &rb_objspace;
 +
    int full_mark = TRUE, immediate_mark = TRUE, immediate_sweep = TRUE;
 +
    VALUE opt = Qnil;
 +
    static ID keyword_ids[3];
 +
 
 +
    rb_scan_args(argc, argv, "0:", &opt);
 +
 
 +
    if (!NIL_P(opt)) {
 +
        VALUE kwvals[3];
 +
 
 +
        if (!keyword_ids[0]) {
 +
            keyword_ids[0] = rb_intern("full_mark");
 +
            keyword_ids[1] = rb_intern("immediate_mark");
 +
            keyword_ids[2] = rb_intern("immediate_sweep");
 +
        }
 +
 
 +
        rb_get_kwargs(opt, keyword_ids, 0, 3, kwvals);
 +
 
 +
        if (kwvals[0] != Qundef) full_mark = RTEST(kwvals[0]);
 +
        if (kwvals[1] != Qundef) immediate_mark = RTEST(kwvals[1]);
 +
        if (kwvals[2] != Qundef) immediate_sweep = RTEST(kwvals[2]);
 +
    }
 +
 
 +
    garbage_collect(objspace, full_mark, immediate_mark, immediate_sweep, GPR_FLAG_METHOD);
 +
    gc_finalize_deferred(objspace);
 +
 
 +
    return Qnil;
 +
}
 +
</syntaxhighlight>
 +
=مصادر=
 +
* <span> </span>[http://ruby-doc.org/core-2.5.1/GC.html صفحة وحدة GC في توثيق روبي الرسمي].
 
[[تصنيف:Ruby]]
 
[[تصنيف:Ruby]]
 
[[تصنيف:Ruby Methods]]
 
[[تصنيف:Ruby Methods]]

مراجعة 21:12، 22 أكتوبر 2018

توفر الوحدة GC واجهة لتحديد ومسح آلية جمع البيانات المهملة في روبي.

تتوفر أيضًا بعض التوابع الأساسية من خلال الوحدة ObjectSpace.

ويمكن الحصول على المزيد من المعلومات حول تشغيل GC من خلال GC::Profiler.

الثوابت

INTERNAL_CONSTANTS

OPTS

توابع الصنف العام

add_stress_to_class(*args)‎

أمثلة

    static VALUE
rb_gcdebug_add_stress_to_class(int argc, VALUE *argv, VALUE self)
{
    rb_objspace_t *objspace = &rb_objspace;

    if (!stress_to_class) {
        stress_to_class = rb_ary_tmp_new(argc);
    }
    rb_ary_cat(stress_to_class, argv, argc);
    return self;
}

count → Integer

عدد مرات حدوث GC.

إعادة عدد مرات حدوث GC منذ بدء العملية.

أمثلة

               static VALUE
gc_count(VALUE self)
{
    return SIZET2NUM(rb_gc_count());
}

disable → true or false

تعطيل جمع البيانات المهملة، وإعادة true إذا كان جمع البيانات المهملة مُعطَّلًا بالفعل.

GC.disable   #=> false
GC.disable   #=> true

أمثلة

               VALUE
rb_gc_disable(void)
{
    rb_objspace_t *objspace = &rb_objspace;
    int old = dont_gc;

    gc_rest(objspace);

    dont_gc = TRUE;
    return old ? Qtrue : Qfalse;
}

 zero? → true أو false

تفعيل جمع البيانات المهملة، وإعادة true إذا كان جمع البيانات المهملة مُعطَّلًا بالفعل.

GC.disable   #=> false
GC.enable    #=> true
GC.enable    #=> false

أمثلة

 
               VALUE
rb_gc_enable(void)
{
    rb_objspace_t *objspace = &rb_objspace;
    int old = dont_gc;

    dont_gc = FALSE;
    return old ? Qtrue : Qfalse;
}

 latest_gc_info → {:gc_by=>:newobj}‎

latest_gc_info(hash) → hash

latest_gc_info(:major_by) → :malloc

إعادة معلومات حول أحدث عملية جمع البيانات المهملة.

أمثلة

               static VALUE
gc_latest_gc_info(int argc, VALUE *argv, VALUE self)
{
    rb_objspace_t *objspace = &rb_objspace;
    VALUE arg = Qnil;

    if (rb_scan_args(argc, argv, "01", &arg) == 1) {
        if (!SYMBOL_P(arg) && !RB_TYPE_P(arg, T_HASH)) {
            rb_raise(rb_eTypeError, "non-hash or symbol given");
        }
    }

    if (arg == Qnil) {
        arg = rb_hash_new();
    }

    return gc_info_decode(objspace, arg, 0);
}

malloc_allocated_size → Integer

إعادة حجم الذاكرة المخصصة من قِبَل malloc()‎.

ويتوفر فقط إذا بُنيت روبي مع CALC_EXACT_MALLOC_SIZE.

أمثلة

               static VALUE
gc_malloc_allocated_size(VALUE self)
{
    return UINT2NUM(rb_objspace.malloc_params.allocated_size);
}

malloc_allocations → Integer

إعادة عدد عمليات مُخصصات malloc()‎.

ويتوفر فقط إذا بُنيت روبي مع CALC_EXACT_MALLOC_SIZE.

أمثلة

 
               static VALUE
gc_malloc_allocations(VALUE self)
{
    return UINT2NUM(rb_objspace.malloc_params.allocations);
}

remove_stress_to_class(*args)‎

أمثلة

               static VALUE
rb_gcdebug_remove_stress_to_class(int argc, VALUE *argv, VALUE self)
{
    rb_objspace_t *objspace = &rb_objspace;
    int i;

    if (stress_to_class) {
        for (i = 0; i < argc; ++i) {
            rb_ary_delete_same(stress_to_class, argv[i]);
        }
        if (RARRAY_LEN(stress_to_class) == 0) {
            stress_to_class = 0;
        }
    }
    return Qnil;
}

start → nil

start(full_mark: true, immediate_sweep: true) → nil

بدء تجميع البيانات المهملة، ما لم تُعطَّل يدويًا.

يُحدد هذا التابع بوسائط الكلمات المفتاحية قِيَمَها الافتراضية true:

def GC.start(full_mark: true, immediate_sweep: true); end

يُضبط full_mark بالقيمة false لتنفيذ GC ثانوية. يُضبط immediate_sweep بالقيمة false لتأجيل المسح (استخدام المسح البطيء).

ملاحظة: تعتمد وسائط الكلمات المفتاحية هذه على التطبيق والإصدار. وليس من المضمون أن تظل متوافقة في المستقبل، ويمكن تجاهلها إذا كان التطبيق الأساسي لا يدعمها.

أمثلة

               static VALUE
gc_start_internal(int argc, VALUE *argv, VALUE self)
{
    rb_objspace_t *objspace = &rb_objspace;
    int full_mark = TRUE, immediate_mark = TRUE, immediate_sweep = TRUE;
    VALUE opt = Qnil;
    static ID keyword_ids[3];

    rb_scan_args(argc, argv, "0:", &opt);

    if (!NIL_P(opt)) {
        VALUE kwvals[3];

        if (!keyword_ids[0]) {
            keyword_ids[0] = rb_intern("full_mark");
            keyword_ids[1] = rb_intern("immediate_mark");
            keyword_ids[2] = rb_intern("immediate_sweep");
        }

        rb_get_kwargs(opt, keyword_ids, 0, 3, kwvals);

        if (kwvals[0] != Qundef) full_mark = RTEST(kwvals[0]);
        if (kwvals[1] != Qundef) immediate_mark = RTEST(kwvals[1]);
        if (kwvals[2] != Qundef) immediate_sweep = RTEST(kwvals[2]);
    }

    garbage_collect(objspace, full_mark, immediate_mark, immediate_sweep, GPR_FLAG_METHOD);
    gc_finalize_deferred(objspace);

    return Qnil;
}

stat → Hash

stat(hash) → hash

stat(:key) → Numeric

إعادة تجزئة Hash تحتوي على معلومات حول GC.

تتضمن التجزئة معلومات حول الإحصائيات الداخلية حول GC مثل:

{
    :count=>0,
    :heap_allocated_pages=>24,
    :heap_sorted_length=>24,
    :heap_allocatable_pages=>0,
    :heap_available_slots=>9783,
    :heap_live_slots=>7713,
    :heap_free_slots=>2070,
    :heap_final_slots=>0,
    :heap_marked_slots=>0,
    :heap_eden_pages=>24,
    :heap_tomb_pages=>0,
    :total_allocated_pages=>24,
    :total_freed_pages=>0,
    :total_allocated_objects=>7796,
    :total_freed_objects=>83,
    :malloc_increase_bytes=>2389312,
    :malloc_increase_bytes_limit=>16777216,
    :minor_gc_count=>0,
    :major_gc_count=>0,
    :remembered_wb_unprotected_objects=>0,
    :remembered_wb_unprotected_objects_limit=>0,
    :old_objects=>0,
    :old_objects_limit=>0,
    :oldmalloc_increase_bytes=>2389760,
    :oldmalloc_increase_bytes_limit=>16777216
}

 محتويات التجزئة خاصة بالتطبيق ويمكن تغييرها في المستقبل.

ومن المتوقع أن يعمل هذا التابع فقط علي روبي C.

أمثلة

 
               static VALUE
gc_stat(int argc, VALUE *argv, VALUE self)
{
    VALUE arg = Qnil;

    if (rb_scan_args(argc, argv, "01", &arg) == 1) {
        if (SYMBOL_P(arg)) {
            size_t value = gc_stat_internal(arg);
            return SIZET2NUM(value);
        }
        else if (!RB_TYPE_P(arg, T_HASH)) {
            rb_raise(rb_eTypeError, "non-hash or symbol given");
        }
    }

    if (arg == Qnil) {
        arg = rb_hash_new();
    }
    gc_stat_internal(arg);
    return arg;
}

stress → integer, true or false

إعادة الحالة الحالية لوضع الضغط لـ GC.

أمثلة

 
               static VALUE
gc_stress_get(VALUE self)
{
    rb_objspace_t *objspace = &rb_objspace;
    return ruby_gc_stress_mode;
}

stress = flag → flag

تحديث وضع الضغط لـ GC.

عند تفعيل وضع الضغط، يُستدعى GC في كل فرصة GC: كافة عمليات تخصيص الذاكرة والكائنات.

سيؤدي تفعيل وضع الضغط إلى خفض الأداء، ويُستعمل فقط للتنقيح.

يمكن أن تكون الراية true، أو false، أو عدد صحيح مُجرى على بِتاته العامل OR تبعًا للرايات.

0x01:: no major GC
0x02:: no immediate sweep
0x04:: full mark after malloc/calloc/realloc

أمثلة

 
               static VALUE
gc_stress_set_m(VALUE self, VALUE flag)
{
    rb_objspace_t *objspace = &rb_objspace;
    gc_stress_set(objspace, flag);
    return flag;
}

verify_internal_consistency → nil

التحقق من الاتساق الداخلي.

هذا التابع خاص بالتطبيق. يتحقق هذا التابع الآن من تناسق الأجيال إذا كان RGenGC مدعومًا.

أمثلة

 
               static VALUE
gc_verify_internal_consistency(VALUE dummy)
{
    rb_objspace_t *objspace = &rb_objspace;
    struct verify_internal_consistency_struct data = {0};
    struct each_obj_args eo_args;

    data.objspace = objspace;
    gc_report(5, objspace, "gc_verify_internal_consistency: start\n");

    /* check relations */

    eo_args.callback = verify_internal_consistency_i;
    eo_args.data = (void *)&data;
    objspace_each_objects((VALUE)&eo_args);

    if (data.err_count != 0) {
#if RGENGC_CHECK_MODE >= 5
        objspace->rgengc.error_count = data.err_count;
        gc_marks_check(objspace, NULL, NULL);
        allrefs_dump(objspace);
#endif
        rb_bug("gc_verify_internal_consistency: found internal inconsistency.");
    }

    /* check heap_page status */
    gc_verify_heap_pages(objspace);

    /* check counters */

    if (!is_lazy_sweeping(heap_eden) && !finalizing) {
        if (objspace_live_slots(objspace) != data.live_object_count) {
            fprintf(stderr, "heap_pages_final_slots: %d, objspace->profile.total_freed_objects: %d\n",
                    (int)heap_pages_final_slots, (int)objspace->profile.total_freed_objects);
            rb_bug("inconsistent live slot number: expect %"PRIuSIZE", but %"PRIuSIZE".", objspace_live_slots(objspace), data.live_object_count);
        }
    }

#if USE_RGENGC
    if (!is_marking(objspace)) {
        if (objspace->rgengc.old_objects != data.old_object_count) {
            rb_bug("inconsistent old slot number: expect %"PRIuSIZE", but %"PRIuSIZE".", objspace->rgengc.old_objects, data.old_object_count);
        }
        if (objspace->rgengc.uncollectible_wb_unprotected_objects != data.remembered_shady_count) {
            rb_bug("inconsistent old slot number: expect %"PRIuSIZE", but %"PRIuSIZE".", objspace->rgengc.uncollectible_wb_unprotected_objects, data.remembered_shady_count);
        }
    }
#endif

    if (!finalizing) {
        size_t list_count = 0;

        {
            VALUE z = heap_pages_deferred_final;
            while (z) {
                list_count++;
                z = RZOMBIE(z)->next;
            }
        }

        if (heap_pages_final_slots != data.zombie_object_count ||
            heap_pages_final_slots != list_count) {

            rb_bug("inconsistent finalizing object count:\n"
                   "  expect %"PRIuSIZE"\n"
                   "  but    %"PRIuSIZE" zombies\n"
                   "  heap_pages_deferred_final list has %"PRIuSIZE" items.",
                   heap_pages_final_slots,
                   data.zombie_object_count,
                   list_count);
        }
    }

    gc_report(5, objspace, "gc_verify_internal_consistency: OK\n");

    return Qnil;
}

توابع المثيل العام

garbage_collect → nil

GC; garbage_collect → nil

garbage_collect(full_mark: true, immediate_sweep: true) → nil

بدء تجميع البيانات المهملة، ما لم تُعطَّل يدويًا.

يُحدد هذا التابع بوسائط الكلمات المفتاحية قِيَمَها الافتراضية true:

def GC.start(full_mark: true, immediate_sweep: true); end

 يُضبط full_mark بالقيمة false لتنفيذ GC ثانوية. ,يُضبط immediate_sweep بالقيمة false لتأجيل المسح (استخدام المسح البطيء).

ملاحظة: تعتمد وسائط الكلمات المفتاحية هذه على التطبيق والإصدار. وليس من المضمون أن تكون متوافقة في المستقبل، ويمكن تجاهلها إذا كان التطبيق الأساسي لا يدعمها.

أمثلة

 
               static VALUE
gc_start_internal(int argc, VALUE *argv, VALUE self)
{
    rb_objspace_t *objspace = &rb_objspace;
    int full_mark = TRUE, immediate_mark = TRUE, immediate_sweep = TRUE;
    VALUE opt = Qnil;
    static ID keyword_ids[3];

    rb_scan_args(argc, argv, "0:", &opt);

    if (!NIL_P(opt)) {
        VALUE kwvals[3];

        if (!keyword_ids[0]) {
            keyword_ids[0] = rb_intern("full_mark");
            keyword_ids[1] = rb_intern("immediate_mark");
            keyword_ids[2] = rb_intern("immediate_sweep");
        }

        rb_get_kwargs(opt, keyword_ids, 0, 3, kwvals);

        if (kwvals[0] != Qundef) full_mark = RTEST(kwvals[0]);
        if (kwvals[1] != Qundef) immediate_mark = RTEST(kwvals[1]);
        if (kwvals[2] != Qundef) immediate_sweep = RTEST(kwvals[2]);
    }

    garbage_collect(objspace, full_mark, immediate_mark, immediate_sweep, GPR_FLAG_METHOD);
    gc_finalize_deferred(objspace);

    return Qnil;
}

مصادر