2010-09-03 48 views
9

Tôi đang xây dựng một số chuỗi lớn có thời lượng tồn tại ngắn trong ứng dụng. Các đối tượng String có phát triển lớn tùy ý đến giới hạn vật lý của cá thể ruby ​​không? Điều tôi đang tự hỏi là, nếu không có bất kỳ sự can thiệp nào trong việc giới hạn kích thước chuỗi, ứng dụng của tôi sẽ bị hosed bởi hết bộ nhớ, hoặc liệu nó có bị giảm đi một cách duyên dáng hay không.Đối tượng Ruby có giới hạn kích thước không?

Cảm ơn mọi đầu vào!

Trả lời

10

Có giới hạn. A String có thể là 2**31 - 1 (và tương ứng 2**63 - 1 trên ruby ​​64 bit). Bạn có thể thấy giới hạn với:

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

Có nói rằng, trong khi bạn có thể thử để phân bổ một chuỗi lớn nó sẽ có khả năng thất bại (ít nhất là trên một hệ thống 32 bit như thường số tiền tối đa của bộ nhớ là một quá trình có thể phân bổ là giữa 2.5 và 3GB và một chuỗi 2**31 - 1 chiều dài được gần 2GB bởi chính nó) Như đã thấy:.

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

tôi không tin rằng có cách nào để bắt NoMemoryError.

cập nhật để phản ánh những nhận xét từ sepp2k

+3

Trên thực tế nó có thể lớn như '2 ** 31 - 1' (và phù hợp' 2 ** 63 - 1' trên 64 bit ruby). – sepp2k

+0

Có phải các ký tự '2 ** 31 - 1' hoặc' 2 ** 31 -1' không? Ngoài ra, không phải là bắt một 'NoMemoryError' một vấn đề nói rằng' giải cứu ngoại lệ 'chứ không phải là 'cứu hộ' (sau này chỉ giải cứu ngoại lệ tương đối nhẹ)? (Để không nói gì về neversaydie ...) –

+0

'2 ** 31 - 1' byte. Bao gồm 'rescue Exception' không bắt được' NoMemoryError' nhưng nó dường như không thực sự phân bổ (vì nó trả về ngay lập tức.) – rjk

Các vấn đề liên quan