2010-09-03 3 views
9

Я строю несколько больших строк, которые имеют короткое время жизни в приложении. Будут ли объекты String произвольно увеличиваться до физических пределов экземпляра ruby?У объектов Ruby есть ограничение по размеру?

Что мне интересно, если без каких-либо вмешательств в ограничение размера строки мое приложение будет закрыто, если закончится нехватка памяти, или это будет изящно деградировать.

Спасибо за любой ввод!

ответ

10

Существует предел. A String может быть 2**31 - 1 (и соответственно 2**63 - 1 на 64-битном рубине). Вы можете увидеть предел с:

>> s = String.new("1" * (2**32)) 
RangeError: bignum too big to convert into `long' 
    from (irb):3:in `*' 
    from (irb):3 
>> s = String.new("1" * (2**31)) 
RangeError: bignum too big to convert into `long' 
    from (irb):4:in `*' 
    from (irb):4 

Сказав, что, в то время как вы могли бы попытаться выделить строку, он большой, вероятно, потерпеть неудачу (по крайней мере, на 32 битной системе, как правило, максимальный объем памяти, процесс может выделить между 2,5 и 3GB и строкой 2**31 - 1 длиной почти 2 Гб сам по себе) Как видно:.

>> "1" * (2**30) 
NoMemoryError: failed to allocate memory 
    from /usr/lib/ruby/1.8/irb.rb:310:in `inspect' 
    from /usr/lib/ruby/1.8/irb.rb:310:in `output_value' 
    from /usr/lib/ruby/1.8/irb.rb:159:in `eval_input' 
    from /usr/lib/ruby/1.8/irb.rb:271:in `signal_status' 
    from /usr/lib/ruby/1.8/irb.rb:155:in `eval_input' 
    from /usr/lib/ruby/1.8/irb/ruby-lex.rb:244:in `each_top_level_statement' 
    from /usr/lib/ruby/1.8/irb/ruby-lex.rb:230:in `loop' 
    from /usr/lib/ruby/1.8/irb/ruby-lex.rb:230:in `each_top_level_statement' 
    from /usr/lib/ruby/1.8/irb/ruby-lex.rb:229:in `catch' 
    from /usr/lib/ruby/1.8/irb/ruby-lex.rb:229:in `each_top_level_statement' 
    from /usr/lib/ruby/1.8/irb.rb:154:in `eval_input' 
    from /usr/lib/ruby/1.8/irb.rb:71:in `start' 
    from /usr/lib/ruby/1.8/irb.rb:70:in `catch' 
    from /usr/lib/ruby/1.8/irb.rb:70:in `start' 
    from /usr/bin/irb:13 
Maybe IRB bug!! 

Я не верю, что есть какой-нибудь способ, чтобы поймать NoMemoryError.

Обновлено для отражения комментарий от sepp2k

+3

На самом деле это может быть столь же большой, как '2 ** 31 - 1' (и, соответственно,' 2 ** 63 - 1' на 64 битном рубин). – sepp2k

+0

Это символы '2 ** 31 - 1' или' 2 ** 31 -1' байт? Кроме того, не ловит «NoMemoryError» вопрос о том, что «спасательное исключение» вместо «спасения» (последнее только спасает относительно мягкие исключения)? (Не говоря уже о neversaydie ...) –

+0

'2 ** 31 - 1' байт. Включение 'rescue Exception' делает ловушку' NoMemoryError', но похоже, что он фактически не выполняет выделение (так как он немедленно возвращается). – rjk

Смежные вопросы