Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby MRI在Thread.new时复制内存分配_Ruby_Multithreading_Mri - Fatal编程技术网

Ruby MRI在Thread.new时复制内存分配

Ruby MRI在Thread.new时复制内存分配,ruby,multithreading,mri,Ruby,Multithreading,Mri,似乎MRI为每个新线程重复内存分配 我使用UbuntuX64、ruby-2.2.4(rvm),我得到的是: 刚开始的irb: 我看到pmap-d165659760K(已分配内存,或程序堆栈[man-pmap(1)]的“[stack]”内存使用情况: 创建线程时: 我看到pmap-d 1656127352K内存使用情况: 所以,我看到了内存分配的重复59760K->127352K 这种行为类似于fork()调用的结果,该调用用于创建新流程,为新流程创建其调用流程数据的副本(“此上下文中没

似乎MRI为每个新线程重复内存分配

我使用UbuntuX64、ruby-2.2.4(rvm),我得到的是:

刚开始的irb:

我看到
pmap-d1656
59760K(已分配内存,或程序堆栈[man-pmap(1)]的“[stack]”内存使用情况:

创建线程时:

我看到
pmap-d 1656
127352K内存使用情况:

所以,我看到了内存分配的重复59760K->127352K


这种行为类似于
fork()
调用的结果,该调用用于创建新流程,为新流程创建其调用流程数据的副本(“此上下文中没有“写时拷贝”)

但线程是在同一进程中创建的,并共享其数据,它看起来很奇怪

实际上,这意味着Ruby中的线程在内存使用方面具有类似于进程的限制:当分配的内存接近物理内存大小时,新线程的创建将失败

我很好奇,为什么

更新

这不是复制内存,而是为每个线程分配~50K的额外内存。
感谢@tadman的建议,这是一种开销,而不是以fork()的方式复制内存。

每个线程都必须为堆栈分配足够的内存,堆栈大小由定义,但即使如此,这也不能解释此处看到的所有内存使用情况。我已经在Fedora机器上复制到一定程度,但我可以毫无问题地运行约500个线程。@tadman,是的,我知道线程数的限制可能看起来并不重要,但我的问题来自一个真实的案例,我在不太小的Rails项目中使用了线程,我得到了内存的限制。但问题是,如果线程已经有了内存空间,为什么它必须分配更多内存?它使用共享对象,从这点上看,它只是一个并发执行的例程。即使它创建了变量——就像其他块中的其他变量一样,不是吗?我不是100%确定MRI的内部结构,但我知道它在全局解释器锁和各种历史兼容性方面有很多问题。新线程确实需要它自己的一些东西的副本,但是随着改进的进行,它需要的东西在版本1.9到2.4之间有很大的不同。堆是共享的,但其他元素不是,特别是堆栈。看来你的建议很重要。我尝试过用
arr=10000000.times.injection([]){a,I | aIf分配一些内存,如果你能想出更多关于分配内容的具体指标,如果这确实是错误的,我相信Ruby性能团队可能会感兴趣。我不确定MRI中的线程C代码有多粗糙,但这是一个开始挖掘的地方。