|
|
(3 مراجعات متوسطة بواسطة مستخدمين اثنين آخرين غير معروضة) |
سطر 1: |
سطر 1: |
− | توفر الوحدة GC واجهة لتحديد ومسح آلية جمع البيانات المهملة في روبي. | + | <noinclude>{{DISPLAYTITLE:الوحدة <code>GC</code> في روبي}}</noinclude> |
| + | توفر الوحدة <code>GC</code> واجهةً لتحديد ومسح آلية جمع البيانات المهملة (garbage collection) في روبي. |
| | | |
− | تتوفر أيضًا بعض التوابع الأساسية من خلال الوحدة [[Ruby/ObjectSpace|ObjectSpace]]. | + | تتوفر أيضًا بعض التوابع الأساسية من خلال الوحدة [[Ruby/ObjectSpace|<code>ObjectSpace</code>]]. |
| | | |
− | ويمكن الحصول على المزيد من المعلومات حول تشغيل GC من خلال [[Ruby/GC::Profiler|GC::Profiler]].
| + | يمكن الحصول على المزيد من المعلومات حول تشغيل الوحدة <code>GC</code> من خلال الوحدة [[Ruby/GC::Profiler|<code>GC::Profiler</code>]]. |
| | | |
− | === الثوابت ===
| + | == الثوابت == |
− | <code>INTERNAL_CONSTANTS</code>
| |
| | | |
− | <code>OPTS</code> | + | === <code>INTERNAL_CONSTANTS</code> === |
− | ===توابع الصنف العام===
| |
| | | |
− | === <code>add_stress_to_class(*args)</code> === | + | === <code>OPTS</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) {
| + | ==توابع الصنف العامة== |
− | stress_to_class = rb_ary_tmp_new(argc);
| + | ===<code>[[Ruby/GC/add_stress_to_class|add_stress_to_class]]</code>=== |
− | }
| + | ===<code>[[Ruby/GC/count|count]]</code>=== |
− | rb_ary_cat(stress_to_class, argv, argc);
| + | يعدُّ عدد مرات حدوث الوحدة <code>[[Ruby/GC|GC]]</code>. |
− | return self;
| |
− | }
| |
− |
| |
− | </syntaxhighlight> | |
| | | |
− | === <code>count → Integer</code> === | + | ===<code>[[Ruby/GC/disable|disable]]</code>=== |
− | عدد مرات حدوث GC.
| + | يعطِّل جمع البيانات المهملة، ويعيد القيمة <code>true</code> إذا كان جمع البيانات المهملة مُعطَّلًا مسبقًا. |
| | | |
− | إعادة عدد مرات حدوث GC منذ بدء العملية.
| + | ===<code>[[Ruby/GC/enable|enable]]</code>=== |
| + | يفعِّل جمع البيانات المهملة، ويعيد القيمة <code>true</code> إذا كان جمع البيانات المهملة مُعطَّلًا مسبقًا. |
| | | |
− | أمثلة<syntaxhighlight lang="ruby">
| + | ===<code>[[Ruby/GC/latest_gc_info|latest_gc_info]]</code>=== |
− | static VALUE
| + | يعيد معلومات حول أحدث عملية جمعٍ للبيانات المهملة. |
− | gc_count(VALUE self)
| |
− | {
| |
− | return SIZET2NUM(rb_gc_count());
| |
− | }
| |
− |
| |
− | </syntaxhighlight> | |
| | | |
− | === <code>disable → true or false</code> === | + | ===<code>[[Ruby/GC/malloc_allocated_size|malloc_allocated_size]]</code>=== |
− | تعطيل جمع البيانات المهملة، وإعادة <code>true</code> إذا كان جمع البيانات المهملة مُعطَّلًا بالفعل.<syntaxhighlight lang="ruby">
| + | يعيد حجم الذاكرة التي حُجزَت من قِبَل <code>malloc()</code>. |
− | 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);
| + | ===<code>[[Ruby/GC/malloc_allocations|malloc_allocations]]</code>=== |
| + | يعيد عدد عمليات الحجز التي أجريت باستعمال <code>malloc()</code>. |
| | | |
− | dont_gc = TRUE;
| + | ===<code>[[Ruby/GC/remove_stress_to_class|remove_stress_to_class]]</code>=== |
− | return old ? Qtrue : Qfalse;
| + | ===<code>[[Ruby/GC/start|start]]</code>=== |
− | }
| + | يبدأ تجميع البيانات المهملة، ما لم تُعطَّل يدويًا. |
− |
| |
− | </syntaxhighlight> | |
| | | |
− | === <code>zero? → true أو false</code> === | + | ===<code>[[Ruby/GC/stat|stat]]</code>=== |
− | تفعيل جمع البيانات المهملة، وإعادة <code>true</code> إذا كان جمع البيانات المهملة مُعطَّلًا بالفعل.<syntaxhighlight lang="ruby">
| + | يعيد [[Ruby/Hash|جدول Hash]] يحتوي على معلومات حول <code>GC</code>. ومن المتوقع أن يعمل هذا التابع فقط علي روبي C. |
− | GC.disable #=> false
| |
− | GC.enable #=> true
| |
− | GC.enable #=> false
| |
| | | |
− | </syntaxhighlight>أمثلة<syntaxhighlight lang="ruby"> | + | ===<code>[[Ruby/GC/stress|stress]]</code>=== |
− |
| + | يعيد الحالة الحالية لوضع الضغط الذي يخص جامع البيات المهملة <code>GC</code>. |
− | VALUE
| |
− | rb_gc_enable(void)
| |
− | {
| |
− | rb_objspace_t *objspace = &rb_objspace;
| |
− | int old = dont_gc;
| |
| | | |
− | dont_gc = FALSE;
| + | ===<code>[[Ruby/GC/stress-3D|stress]]</code>=== |
− | return old ? Qtrue : Qfalse;
| + | يحدِّث عند استدعائه بالشكل <code>stress = flag</code> وضع الضغط الذي يخص جامع البيانات المهملة <code>GC</code>. |
− | }
| |
− |
| |
− | </syntaxhighlight> | |
| | | |
− | === <code>latest_gc_info → {:gc_by=>:newobj}</code> === | + | ===<code>[[Ruby/GC/verify_internal_consistency|verify_internal_consistency]]</code>=== |
| + | يتحقَّق من الاتساق الداخلي. |
| | | |
− | === <code>latest_gc_info(hash) → hash</code> === | + | == توابع النسخة العامة == |
| | | |
− | === <code>latest_gc_info(:major_by) → :malloc</code> === | + | ===<code>[[Ruby/GC/garbage_collect|garbage_collect]]</code>=== |
− | إعادة معلومات حول أحدث عملية جمع البيانات المهملة.
| + | يبدأ تجميع البيانات المهملة، ما لم تُعطَّل يدويًا. |
| | | |
− | أمثلة<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>.
| |
− |
| |
− | أمثلة<syntaxhighlight lang="ruby">
| |
− |
| |
− | static VALUE
| |
− | gc_malloc_allocated_size(VALUE self)
| |
− | {
| |
− | return UINT2NUM(rb_objspace.malloc_params.allocated_size);
| |
− | }
| |
− | </syntaxhighlight><code>malloc_allocations → Integer</code>
| |
− |
| |
− | إعادة عدد عمليات مُخصصات <code>malloc()</code>.
| |
− |
| |
− | ويتوفر فقط إذا بُنيت روبي مع <code>CALC_EXACT_MALLOC_SIZE</code>.
| |
− |
| |
− | أمثلة<syntaxhighlight lang="ruby">
| |
− |
| |
− | static VALUE
| |
− | gc_malloc_allocations(VALUE self)
| |
− | {
| |
− | return UINT2NUM(rb_objspace.malloc_params.allocations);
| |
− | }
| |
− |
| |
− | </syntaxhighlight>
| |
− |
| |
− | === <code>remove_stress_to_class(*args)</code> ===
| |
− | أمثلة<syntaxhighlight lang="ruby">
| |
− |
| |
− | 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;
| |
− | }
| |
− |
| |
− | </syntaxhighlight>
| |
− |
| |
− | === <code>start → nil</code> ===
| |
− |
| |
− | === <code>start(full_mark: true, immediate_sweep: true) → nil</code> ===
| |
− | بدء تجميع البيانات المهملة، ما لم تُعطَّل يدويًا.
| |
− |
| |
− | يُحدد هذا التابع بوسائط الكلمات المفتاحية قِيَمَها الافتراضية <code>true</code>:<syntaxhighlight lang="ruby">
| |
− | def GC.start(full_mark: true, immediate_sweep: true); end
| |
− |
| |
− | </syntaxhighlight>يُضبط <code>full_mark</code> بالقيمة <code>false</code> لتنفيذ GC ثانوية. يُضبط <code>immediate_sweep</code> بالقيمة <code>false</code> لتأجيل المسح (استخدام المسح البطيء).
| |
− |
| |
− | ملاحظة: تعتمد وسائط الكلمات المفتاحية هذه على التطبيق والإصدار. وليس من المضمون أن تظل متوافقة في المستقبل، ويمكن تجاهلها إذا كان التطبيق الأساسي لا يدعمها.
| |
− |
| |
− | أمثلة<syntaxhighlight lang="ruby">
| |
− |
| |
− | 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>
| |
− |
| |
− | === <code>stat → Hash</code> ===
| |
− |
| |
− | === <code>stat(hash) → hash</code> ===
| |
− |
| |
− | === <code>stat(:key) → Numeric</code> ===
| |
− | إعادة تجزئة Hash تحتوي على معلومات حول 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.
| |
− |
| |
− | أمثلة<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");
| |
− | }
| |
− | }
| |
− |
| |
− | if (arg == Qnil) {
| |
− | arg = rb_hash_new();
| |
− | }
| |
− | gc_stat_internal(arg);
| |
− | return arg;
| |
− | }
| |
− |
| |
− | </syntaxhighlight>
| |
− |
| |
− | === <code>stress → integer, true or false</code> ===
| |
− | إعادة الحالة الحالية لوضع الضغط لـ GC.
| |
− |
| |
− | أمثلة<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 في كل فرصة GC: كافة عمليات تخصيص الذاكرة والكائنات.
| |
− |
| |
− | سيؤدي تفعيل وضع الضغط إلى خفض الأداء، ويُستعمل فقط للتنقيح.
| |
− |
| |
− | يمكن أن تكون الراية <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 */
| |
− |
| |
− | 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;
| |
− | }
| |
− |
| |
− | </syntaxhighlight>
| |
− | ===توابع المثيل العام===
| |
− |
| |
− | === <code>garbage_collect → nil</code> ===
| |
− |
| |
− | === <code>GC; garbage_collect → nil</code> ===
| |
− |
| |
− | === <code>garbage_collect(full_mark: true, immediate_sweep: true) → nil</code> ===
| |
− | بدء تجميع البيانات المهملة، ما لم تُعطَّل يدويًا.
| |
− |
| |
− | يُحدد هذا التابع بوسائط الكلمات المفتاحية قِيَمَها الافتراضية <code>true</code>:<syntaxhighlight lang="ruby">
| |
− | def GC.start(full_mark: true, immediate_sweep: true); end
| |
− |
| |
− | </syntaxhighlight> يُضبط <code>full_mark</code> بالقيمة <code>false</code> لتنفيذ GC ثانوية. ,يُضبط <code>immediate_sweep</code> بالقيمة <code>false</code> لتأجيل المسح (استخدام المسح البطيء).
| |
− |
| |
− | ملاحظة: تعتمد وسائط الكلمات المفتاحية هذه على التطبيق والإصدار. وليس من المضمون أن تكون متوافقة في المستقبل، ويمكن تجاهلها إذا كان التطبيق الأساسي لا يدعمها.
| |
− |
| |
− | أمثلة<syntaxhighlight lang="ruby">
| |
− |
| |
− | 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 في توثيق روبي الرسمي]. | + | * <span> </span>[http://ruby-doc.org/core-2.5.1/GC.html صفحة الوحدة GC في توثيق روبي الرسمي]. |
| [[تصنيف:Ruby]] | | [[تصنيف:Ruby]] |
− | [[تصنيف:Ruby Methods]] | + | [[تصنيف:Ruby Module]] |
| + | [[تصنيف:Ruby GC]] |