2010-09-03 7 views
9

Je construis de grandes chaînes qui ont une courte durée de vie dans l'application. Les objets String deviendront-ils arbitrairement grands jusqu'aux limites physiques de l'instance de ruby? Ce que je me demande, c'est si, sans aucune intervention dans la limitation de la taille de la chaîne, mon application serait arrosée par manque de mémoire, ou si elle se dégraderait gracieusement.Est-ce que les objets Ruby ont une taille limite?

Merci pour toute contribution!

Répondre

10

Il existe une limite. Un String peut être 2**31 - 1 (et en conséquence 2**63 - 1 sur le rubis 64 bits). Vous pouvez voir la limite avec:

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

Cela dit, alors que vous pouvez essayer d'allouer une chaîne grand, il risque d'échouer (au moins sur un système 32 bits en général la quantité maximale de mémoire qu'un processus peut allouent est compris entre 2,5 et 3 Go et une chaîne de longueur 2**31 - 1 est presque 2 Go par lui-même) Comme on le voit.

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

Je ne crois pas qu'il y ait un moyen de prendre le NoMemoryError.

Mise à jour pour refléter le commentaire de sepp2k

+3

En fait, il peut être aussi grand que '2 ** 31 - 1' (et par conséquent' 2 ** 63 - 1' sur 64 rubis bits). – sepp2k

+0

Est-ce que les caractères '2 ** 31 - 1' ou' 2 ** 31 -1' octets? En outre, ne pas attraper un 'NoMemoryError' une question de dire' rescue Exception' plutôt que 'rescue' (ce dernier ne sauvant que des exceptions relativement légères)? (Pour ne rien dire de neversaydie ...) –

+0

'2 ** 31 - 1' octets. Y compris 'rescue Exception' attrape le' NoMemoryError' mais il ne semble pas réellement effectuer l'allocation (puisqu'il revient immédiatement). – rjk

Questions connexes