为什么 GC stat minor_gc_count 递减?

Mar*_*rce 6 garbage-collection ruby-on-rails heroku

我们有一个 heroku 应用程序。当我检查GC.stat早上时GC.stat[:minor_gc_count]是 51。当天晚些时候是 50。

根据我的理解,这应该是垃圾收集器做小扫的次数,所以第二天早上起来是有道理的,但为什么会减少呢?

>heroku run rails c --remote production
Running rails c on ? ... up, run.2287 (Standard-1X)
Loading production environment (Rails 5.2.2.1)
irb(main):001:0> GC.stat
=> {:count=>63, :heap_allocated_pages=>1753, :heap_sorted_length=>1753, :heap_allocatable_pages=>0, :heap_available_slots=>714528, :heap_live_slots=>713742, :heap_free_slots=>786, :heap_final_slots=>0, :heap_marked_slots=>471239, :heap_eden_pages=>1753, :heap_tomb_pages=>0, :total_allocated_pages=>1753, :total_freed_pages=>0, :total_allocated_objects=>2802530, :total_freed_objects=>2088788, :malloc_increase_bytes=>65256, :malloc_increase_bytes_limit=>32225676, :minor_gc_count=>51, :major_gc_count=>12, :remembered_wb_unprotected_objects=>4626, :remembered_wb_unprotected_objects_limit=>8538, :old_objects=>458044, :old_objects_limit=>838856, :oldmalloc_increase_bytes=>65712, :oldmalloc_increase_bytes_limit=>19737900}
irb(main):002:0> exit
**Airbrake: closed
>heroku run rails c --remote production
Running rails c on ?... up, run.7226 (Standard-1X)
Loading production environment (Rails 5.2.2.1)
irb(main):001:0> GC.stat
=> {:count=>62, :heap_allocated_pages=>1618, :heap_sorted_length=>1913, :heap_allocatable_pages=>295, :heap_available_slots=>659511, :heap_live_slots=>659395, :heap_free_slots=>116, :heap_final_slots=>0, :heap_marked_slots=>467961, :heap_eden_pages=>1618, :heap_tomb_pages=>0, :total_allocated_pages=>1618, :total_freed_pages=>0, :total_allocated_objects=>2726093, :total_freed_objects=>2066698, :malloc_increase_bytes=>5662240, :malloc_increase_bytes_limit=>24780563, :minor_gc_count=>50, :major_gc_count=>12, :remembered_wb_unprotected_objects=>4632, :remembered_wb_unprotected_objects_limit=>9262, :old_objects=>456572, :old_objects_limit=>913146, :oldmalloc_increase_bytes=>7549584, :oldmalloc_increase_bytes_limit=>19737900}
Run Code Online (Sandbox Code Playgroud)

eda*_*edl 1

问题可能出在测试本身。当您运行时GC.stat,它将返回有关当前正在运行的进程的信息。这很好。问题是每次你跑步的时候

heroku run rails c --remote production
Run Code Online (Sandbox Code Playgroud)

在您的控制台中,它不会连接到您当前在 Heroku 上运行的应用程序的进程。它将为控制台启动一个新进程GC.stat,您将返回这个新创建的进程,而不是您的应用程序响应 Web 请求的进程。这就是为什么它如此低,甚至可能下降的原因。

其实你可以自己测试一下。当您连接到 Heroku 上的 Rails 控制台时,运行以下 ruby​​ 代码:

Process.pid
Run Code Online (Sandbox Code Playgroud)

它将返回当前进程的 ID。然后断开与 Heroku 的连接并重新连接并Process.pid再次运行。您将看到它将返回不同的进程 ID,因为当您与控制台断开连接并为新连接创建新进程时,它会停止前一个进程。

您还可以尝试GC.stat在这些连接中运行,您会发现它们可能会有所不同,并且这些连接之间的计数可能会上下波动,这是因为进程彼此不依赖。