2010-09-03 15 views
9

Estoy construyendo algunas cadenas grandes que tienen una vida útil corta dentro de la aplicación. ¿Los objetos String crecerán arbitrariamente grandes hasta los límites físicos de la instancia de ruby?¿Los objetos Ruby tienen un límite de tamaño?

Lo que me pregunto es si, sin ninguna intervención en la limitación del tamaño de la cadena, mi aplicación se mancharía por falta de memoria, o si se degradaría con gracia.

¡Gracias por cualquier entrada!

Respuesta

10

Hay un límite. Un String puede ser 2**31 - 1 (y por consiguiente 2**63 - 1 en ruby ​​de 64 bits). Se puede ver el límite con:

>> 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 

Una vez dicho esto, mientras que se podría tratar de asignar una cadena tan grande que es probable que falle (por lo menos en un sistema de 32 bits que normalmente la cantidad máxima de memoria que un proceso puede asignar es de entre 2,5 y 3 GB y una cadena 2**31 - 1 longitud es de casi 2 GB por sí mismo) Como se ha visto:.

>> "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!! 

no creo hay alguna manera de coger el NoMemoryError.

actualiza para reflejar el comentario de sepp2k

+3

En realidad puede ser tan grande como '2 ** 31 - 1' (y, en consecuencia' 2 ** 63 - 64 1' ​​en rubí bits). – sepp2k

+0

¿Es eso '2 ** 31 - 1' caracteres o' 2 ** 31 -1' bytes? Además, ¿no se detecta un 'NoMemoryError' al decir 'Excepción de rescate' en lugar de 'rescatar' (este último solo rescata excepciones relativamente leves)? (Para no decir nada de neversaydie ...) –

+0

'2 ** 31 - 1' bytes. La inclusión de 'rescue Exception' detecta el' NoMemoryError', pero no parece que realmente realice la asignación (ya que se devuelve inmediatamente). – rjk

Cuestiones relacionadas