为什么Ruby有时只释放内存

为什么Ruby有时只释放内存

本文介绍了为什么Ruby有时只释放内存?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

取决于我如何生成字符串,Ruby会将内存释放到操作系统,或者不会释放.第一个测试代码将占用约235MB

Depending on how I generate a string Ruby will release the memory to the OS or it won't. The first test code will take up about 235MB

size = 2**22
string = '!@#$%^&*()-+~`a1234567890abcdefghijklmnopqrstuvwxyz' * size
puts 'Sleeping...'
sleep(5)
string = nil
GC.start
puts 'Just sitting here..'
gets.chomp

在调用GC.start之后,测试使用的内存将缩小到几千字节.但是,如果我对string = (0...size).map { (65 + rand(26)).chr }.join运行相同的测试,则调用GC.start后,内存将达到250MB,而实际使用的内存将增加至290MB.

After GC.start is called, memory used by the test will shrink back to a few kilobytes. But if I run the same test with string = (0...size).map { (65 + rand(26)).chr }.join, memory will shoot up to 250MB and memory use will actually increase to 290MB after calling GC.start.

我正在使用Ruby 1.9.3-p448,因为我正在处理的项目需要它.尽管我将在Ruby 2.2上对其进行测试,然后返回结果.

I'm using Ruby 1.9.3-p448 as the project I'm working on requires it. Although I'll test it on Ruby 2.2 and come back with results.

在Ruby 2.1中运行测试代码(RVM中没有Ruby 2.2,我只是想快速运行测试)产生了相似的结果.内存仍然没有减少到合理的状态.它从234MB BGC(在GC.start之前)增加到197MB AGC.注意:内存大小有所不同,因为我在另一台计算机上运行了内存,但是特定大小并不重要,相对增加和减少(或不减少)都是如此.

EDIT 2: Running the test code in Ruby 2.1 (Ruby 2.2 wasn't available in RVM and I just wanted to run the test quickly) gave similar results. Memory still didn't decrease to a reasonable state. It went from 234MB BGCs (before GC.start) to 197MB AGCs. Note: the memory sizes were different because I ran it on a different machine but the specific sizes don't matter just the relative increases and decreases (or non-decreases).

推荐答案

Ruby MRI不会将内存释放回操作系统.

Ruby MRI does not release memory back to the OS.

这是我在OSX 10.10上使用Ruby MRI 2.2看到的,使用典型的ps -o rss:

Here's what I see with Ruby MRI 2.2 on OSX 10.10, using typical ps -o rss:

  • 使用*分配大字符串需要约220MB.

  • Allocating the big string by using * uses ~220MB.

使用map分配大字符串需要约340MB.

Allocating the big string by using map uses ~340MB.

在我的系统上,GC.start对RSS没有任何作用.换句话说,我看到RAM使用率保持不变.

On my system, the GC.start doesn't do anything to the RSS. In other words, I see the RAM usage stay the same.

值得注意的是,map正在使用大量RAM:

Notably, the map is using a lot of RAM:

  • (0...size).map{ '' }使用约300MB.
  • (0...size).map{ '' } uses ~300MB.

当我循环播放您的示例时,会出现一些有趣的事情:

When I loop your examples, something interesting emerges:

  • 使用*分配大字符串将继续使用相同的RAM,即RSS的变化不大.

  • Allocating the big string by using * continues to use the same RAM, i.e. RSS doesn't change much.

使用map分配大字符串每个循环将增加约40M.

Allocating the big string by using map grows by ~40M per loop.

每个循环仅执行(0...size).map{ '' }即可增加约40M.

Doing just (0...size).map{ '' } grows by ~40M per loop.

这告诉我Ruby map可能存在与RAM有关的问题.这并不完全是问题,因为Ruby并未引发NoMemoryException,但是这似乎不是对RAM的非最佳使用.

This shows me that Ruby map may have a RAM-related issue. It's not exactly a problem, because Ruby isn't raising NoMemoryException, but does seem to be a non-optimal use of RAM.

这篇关于为什么Ruby有时只释放内存?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 08:09