我的问题是:如何克隆红宝石

何时确切发生克隆?


因此,我所拥有的只是函数cur_memory ,它以Gb返回当前使用的内存,包含长文本的字符串s1和从prev复制的s2

def cur_memory
  %x(free).split("\n")[1].split(' ')[2].to_f / 10**6
end

注意,这需要3 GB的内存! (或者您可以在下面的8中替换9)

m = cur_memory              # snapshot
s1 = '0'*10**9              # create long string

p (cur_memory - m).round 3  # 1st output
s2 = s1.clone
p (cur_memory - m).round 3  # 2nd output
s1[0] = '2'
p (cur_memory - m).round 3  # 3rd output
s2[0] = '1'
p (cur_memory - m).round 3  # 4th output

输出:

0.978
0.978
1.957
2.936

  1. 第一个输出还可以!
  2. 为什么在第一个输出之后什么都没有改变?
  3. 好的,也许红宝石很聪明,也许有点懒惰。 (但无论如何,我想知道)
  4. 但是现在是WTF吗? 3 GB而不是2 GB?

PS已在Ruby 2.1.0和2.4.0上测试

===============>>#1 票数:0

我在MacOS X上的MRI 2.4和JRuby 9.1.2中对此进行了测试。在MRI和JRuby中,我都发现它们作为脚本运行时的行为类似。 当修改原始副本或副本时,即不再匹配时,将为克隆分配内存。

def cur_memory
  pid = Process.pid
  `ps -p#{pid} -o rss=`.to_f / 1024
end

def diff(m)
  (cur_memory - m).round 3
end

m = cur_memory              # snapshot

s1 = '0'*10**8              # create long string
p "1st output #{diff(m)} MB"

s2 = s1.clone
p "2nd output #{diff(m)} MB"

s2[0] = '2'
p "3rd output #{diff(m)} MB"

s1[0] = '1'
p "4th output #{diff(m)} MB"

s2[0] = '1'
p "5th output #{diff(m)} MB"

s1[0] = '2'
p "6th output #{diff(m)} MB"

输出:

"1st output 95.379 MB"
"2nd output 95.41 MB"
"3rd output 190.781 MB"
"4th output 286.152 MB"
"5th output 286.152 MB"
"6th output 286.152 MB"

在JRuby中,我们可以观察堆内存的分配方式。 它表明,分配克隆后,修改不会增加堆使用率。

require 'java'

java_import 'java.lang.System'
java_import 'java.lang.management.ManagementFactory'

def cur_heap
  ManagementFactory.getMemoryMXBean.getHeapMemoryUsage.getUsed.to_f / (1024 * 1024)
end

def cur_memory
  pid = Process.pid
  `ps -p#{pid} -o rss=`.to_f / 1024
end

def diff_mem(m)
  (cur_memory - m).round 3
end

def diff_heap(m)
  (cur_heap - m).round 3
end

System.gc
m = cur_memory              # snapshot
h = cur_heap

s1 = '0'*10**8              # create long string
System.gc
p "1st output #{diff_heap(h)}/#{diff_mem(m)} MB"

s2 = s1.clone
System.gc
p "2nd output #{diff_heap(h)}/#{diff_mem(m)} MB"

s2[0] = '2'
System.gc
p "3rd output #{diff_heap(h)}/#{diff_mem(m)} MB"

s1[0] = '1'
System.gc
p "4th output #{diff_heap(h)}/#{diff_mem(m)} MB"

s2[0] = '1'
System.gc
p "5th output #{diff_heap(h)}/#{diff_mem(m)} MB"

s1[0] = '2'
System.gc
p "6th output #{diff_heap(h)}/#{diff_mem(m)} MB"

输出:

"1st output 95.392/103.844 MB"
"2nd output 94.503/101.262 MB"
"3rd output 189.871/200.262 MB"
"4th output 189.876/299.277 MB"
"5th output 189.877/299.328 MB"
"6th output 189.878/299.41 MB"

注意:使用IRB时,MRI行为略有不同。 创建克隆后,它将显示内存使用率增加。

  ask by Sagid translate from so

未解决问题?本站智能推荐: