【问题标题】:How to test "loop" vs "while" loop memory usage without GC in Ruby如何在 Ruby 中测试没有 GC 的“循环”与“while”循环内存使用情况
【发布时间】:2020-01-07 15:56:18
【问题描述】:

我在 Ruby 2.4 和 2.7 版本中测试过代码:

1.

    GC.disable

    while true
        ?a
    end

2.

    GC.disable
    puts ?a while true

3.

    GC.disable

    loop do
        ?a
    end

4.

    GC.disable

    loop do
        puts ?a
    end

示例 1 到 4 应该使用所有可用内存和交换,因为它们都在无限循环中创建字符串 a,这样:

  • GC 已禁用。
  • 字符串a 未冻结。

但是 #1 在执行时不会消耗超过一个字节。 #2、#3 和#4 使用尽可能多的内存。在我的系统上,它们每秒消耗大约 250 MB 左右。正如预期的那样,CPU 内核的使用率为 100%。

为什么#1 几乎不消耗任何内存,而其他人在很短的时间内使用所有可用的系统内存?

【问题讨论】:

  • 我注意到的事情没有特别的顺序:在我的系统上,代码 2 也消耗了所有可用内存。通过ruby --dump=insns <filename> 检查指令序列时,似乎Ruby 优化了代码1 中的文字。它还表明loop 创建了一个块(即新的变量范围),而while 没有。添加# frozen_string_literal: true 消除了所有 4 的内存消耗。
  • 糟糕,2 也属于 3 和 4 的类别(内核正在将页面写入 zram,没有注意到),现在已编辑。谢谢...

标签: ruby garbage-collection


【解决方案1】:

Stefan 在他的评论中是正确的,因为 while 循环没有创建新的范围。

还要注意puts 方法的效果。每次调用字符串时,它都会在内存中分配一个新对象。

require "benchmark/memory"

Benchmark.memory do |x|
  x.report("Test1") { puts ?a }
  x.report("Test2") { ?a }
  x.report("Test3") { puts ?a; puts ?a; puts ?a; puts ?a; puts ?a; puts ?a; puts ?a; puts ?a; puts ?a; puts ?a }
  x.report("Test4") { ?a; ?a; ?a; ?a; ?a; ?a; ?a; ?a; ?a; ?a; }

  x.compare!
end

输出:

Calculating -------------------------------------
           Test1    40.000  memsize (     0.000  retained)
                     1.000  objects (     0.000  retained)
                     1.000  strings (     0.000  retained)
           Test2    40.000  memsize (     0.000  retained)
                     1.000  objects (     0.000  retained)
                     1.000  strings (     0.000  retained)
           Test3   400.000  memsize (     0.000  retained)
                    10.000  objects (     0.000  retained)
                     1.000  strings (     0.000  retained)
           Test4    40.000  memsize (     0.000  retained)
                     1.000  objects (     0.000  retained)
                     1.000  strings (     0.000  retained)

Comparison:
           Test1:         40 allocated
           Test2:         40 allocated - same
           Test3:        400 allocated - 10.00x more
           Test4:         40 allocated - same

【讨论】:

    猜你喜欢
    • 2022-11-05
    • 2017-10-30
    • 1970-01-01
    • 1970-01-01
    • 2016-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多