I was ready an article on Ruby's GC (Garbage Collection) today and I got confused over few points.
我今天准备了一篇关于Ruby的GC(垃圾收集)的文章,我对这几点感到困惑。
Let's say we are using Unicorn to serve our site. Unicorn uses worker processes to handle requests. Worker processes normally are forked processes of parent / master process. Now my question is that where does GC happen? I mean do each forked process have it's own copy of Ruby process running and GC happens for each forked process separately or do each forked process use same Ruby process i.e. from master process and GC happens there? If latter is true then how does forked process share things such as Ruby from parent process.
假设我们使用Unicorn来服务我们的网站。 Unicorn使用工作进程来处理请求。工作进程通常是父/主进程的分叉进程。现在我的问题是GC在哪里发生?我的意思是每个分叉进程都有自己的Ruby进程运行副本,并且每个分叉进程单独发生GC,或者每个分叉进程是否使用相同的Ruby进程,即主进程和GC在那里发生?如果后者是真的,那么分叉进程如何从父进程共享诸如Ruby之类的东西。
To my understanding each forked process have it's own version of Ruby running which gets copied when child process was forked.
据我所知,每个分叉进程都有自己的Ruby运行版本,当子进程被分叉时会被复制。
Any help is highly appreciated.
任何帮助都非常感谢。
Thanks.
谢谢。
1 个解决方案
#1
0
It used to be true that each forked process got its own copy of the entire memory space of the parent process. This is why process based web servers for Ruby tended to need so much memory until recently.
过去,每个分叉进程都拥有自己进程的整个内存空间的副本。这就是为什么Ruby的基于流程的Web服务器直到最近才需要这么多内存的原因。
As of Ruby 2.0 however, forked processes now adhere to the Copy on Write principle. That is to say, a forked process shares as much data with its parent process as possible. This means that child processes use a lot less memory than they used to as they no longer need to copy the entire memory space of their parent process. When a child process needs to modify a part of the memory it shares with its parent process (or the parent process needs to modify a part of the memory it shares with a child), the child process will make a copy of just that part. That's why it's called Copy on Write :)
但是,从Ruby 2.0开始,分叉进程现在遵循Copy on Write原则。也就是说,分叉进程与其父进程共享尽可能多的数据。这意味着子进程使用的内存比以前少得多,因为它们不再需要复制其父进程的整个内存空间。当子进程需要修改它与其父进程共享的内存的一部分时(或者父进程需要修改它与子进程共享的内存的一部分),子进程将只复制该部分。这就是为什么它被称为Copy on Write :)
Regarding Garbage Collection, that happens in each Ruby process. The above explanation should hopefully make it clear why such an approach works.
关于垃圾收集,这发生在每个Ruby进程中。上述解释应该有希望说明为什么这种方法有效。
#1
0
It used to be true that each forked process got its own copy of the entire memory space of the parent process. This is why process based web servers for Ruby tended to need so much memory until recently.
过去,每个分叉进程都拥有自己进程的整个内存空间的副本。这就是为什么Ruby的基于流程的Web服务器直到最近才需要这么多内存的原因。
As of Ruby 2.0 however, forked processes now adhere to the Copy on Write principle. That is to say, a forked process shares as much data with its parent process as possible. This means that child processes use a lot less memory than they used to as they no longer need to copy the entire memory space of their parent process. When a child process needs to modify a part of the memory it shares with its parent process (or the parent process needs to modify a part of the memory it shares with a child), the child process will make a copy of just that part. That's why it's called Copy on Write :)
但是,从Ruby 2.0开始,分叉进程现在遵循Copy on Write原则。也就是说,分叉进程与其父进程共享尽可能多的数据。这意味着子进程使用的内存比以前少得多,因为它们不再需要复制其父进程的整个内存空间。当子进程需要修改它与其父进程共享的内存的一部分时(或者父进程需要修改它与子进程共享的内存的一部分),子进程将只复制该部分。这就是为什么它被称为Copy on Write :)
Regarding Garbage Collection, that happens in each Ruby process. The above explanation should hopefully make it clear why such an approach works.
关于垃圾收集,这发生在每个Ruby进程中。上述解释应该有希望说明为什么这种方法有效。