|
|
سطر 1: |
سطر 1: |
| توفر الوحدة GC واجهة لتحديد ومسح آلية جمع البيانات المهملة في روبي. | | توفر الوحدة <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]] |