2010-03-08 42 views
10

Có cách nào trong ruby ​​để lấy địa chỉ bộ nhớ của các đối tượng ..Truy cập địa chỉ bộ nhớ đối tượng trong ruby ​​..?

nói ..

(i = 5) là tốt để có được địa chỉ của mem mà đối tượng 5 ..

tôi đã cố gắng để có được điều này qua một thời gian ..,

Bất kỳ câu trả lời sẽ được thực sự đánh giá cao ...

cảm ơn,

Kính trọng levirg

+10

Tại sao? Bạn đang cố làm gì vậy? – SLaks

Trả lời

3

Tôi không biết cách nào có địa chỉ chính xác, nhưng có thể bạn đang tìm kiếm một phương thức như phương pháp object_id?

Extract từ nó documentation

Trả một định nguyên cho obj.
Cùng một số sẽ được trả lại trên tất cả các cuộc gọi đến id cho một đối tượng nhất định, và không có hai đối tượng đang hoạt động sẽ chia sẻ một id


Ví dụ:

> 5.object_id 
=> 11 
> true.object_id 
=> 2 
7

Ruby Memory Validator sẽ có thể để kéo nó ra nhưng nó không miễn phí.

Aman Gupta patched Joe Damatos memprof nhưng có vẻ như là work in progress và tôi chưa bao giờ chạy nó trên máy tính của mình. Joe có một số bài đăng hay về memprof và các nội dung cấp thấp khác trên số blog của anh ấy.

Bây giờ tôi không chắc là họ thực sự có thể. Số nguyên được lưu trữ dưới dạng FixnumFixnum không phải là đối tượng Ruby thông thường, nó chỉ trông như vậy. Ruby sử dụng một mẹo tăng tốc thông minh với các đối tượng object_id để làm cho các đối tượng chiếm ưu thế. Số thực tế được lưu trữ trong chính số object_id. Đó là lý do tại sao hai Fixnum khác nhau chứa cùng một giá trị có cùng số object_id.

>> x=5 
=> 5 
>> y=5 
=> 5 
>> x.object_id 
=> 11 
>> y.object_id 
=> 11 
>> z=4711 
=> 4711 
>> z.object_id 
=> 9423 

Các object_id của một Fixnum là thực sự được tạo ra bởi chút chuyển sang bên trái và sau đó thiết lập các bit ít quan trọng.

50b101object_id cho 51111 trong hệ nhị phân là 0b1011.

47110b0001001001100111, chuyển trái và thiết lập các bit và bạn nhận 0b0010010011001111 và đó là 9423 mà sẽ xảy ra là object_id cho z trên.

This behaviour có lẽ là triển khai cụ thể nhưng tôi không biết về triển khai Ruby không xử lý Fixnum theo cách này.

Có ít nhất ba đối tượng trực tiếp khác trong Ruby và đó là false, truenil.

>> false.object_id 
=> 0 
>> true.object_id 
=> 2 
>> nil.object_id 
=> 4 
+0

có vẻ như memro wroks tốt cho 64bit, của tôi là 32bit ..... cảm ơn – levirg

+0

Cảm ơn, tôi đã bỏ lỡ điều đó trong readme cho memprof. Tôi cũng trên 32-bit. Xem phần trên để biết cách Ruby lưu trữ Fixnum. –

+0

đó là tuyệt vời, tôi đã học được điều gì đó từ đó ... cảm ơn người đàn ông .. – levirg

0

Chính xác bạn đang cố gắng làm gì?

Hãy nhớ rằng đối tượng Ruby không tương tự trực tiếp với biến trong ngôn ngữ như C hoặc C++. Ví dụ:

a = "foo" 
b = a 
b[2] = 'b' 
b 
    => "fob" 
a 
    => "fob" 
a == b 
    => true 
a.object_id 
    => 23924940 
b.object_id 
    => 23924940 
a.object_id == b.object_id 
    => true 

Thậm chí thông qua ab là các biến riêng biệt, họ được tham chiếu đến các dữ liệu cơ bản giống nhau và có cùng một object_id.

Nếu bạn thấy mình cần phải lấy địa chỉ của một biến, có thể là một cách tiếp cận dễ dàng hơn cho bất cứ điều gì bạn đang cố gắng làm.

+0

Tôi chỉ muốn biết làm thế nào tham chiếu đến các đối tượng làm việc trên ruby, vì vậy tôi nghĩ địa chỉ sẽ hữu ích, để có được những điều thực hiện ..... nếu có bất kỳ cách nào tốt hơn pls giúp tôi ... cảm ơn – levirg

+0

Bạn không cần phải lo lắng về việc tham chiếu một đối tượng trong Ruby. Ngược lại với các ngôn ngữ khác, nơi bạn có thể truyền một đối tượng theo giá trị hoặc tham chiếu, Ruby xử lý tất cả các khía cạnh cấp thấp cho bạn. Tất cả những gì bạn cần làm là sử dụng đối tượng và truyền nó xung quanh như bạn muốn nếu bạn đi qua giá trị trong C. Để biết thêm thông tin về nội bộ của Ruby, xem http://www.ruby-doc.org/docs/ ProgrammingRuby/language.html. – bta

1

Ruby Memory Validator sẽ cung cấp cho bạn địa chỉ bộ nhớ cho đối tượng.

Tác phẩm của Joe Damato (http://timetobleed.com/plugging-ruby-memory-leaks-heapstack-dump-patches-to-help-take-out-the-trash) và (http://timetobleed.com/memprof-a-ruby-level-memory-profiler) dựa trên công việc Xác minh phần mềm đã làm để tạo API kiểm tra bộ nhớ Ruby (http://www.softwareverify.com/ruby/customBuild/index.html).

Joe mô tả điều đó trên blog của mình. Do đó công việc của Joe cũng nên trả lại các địa chỉ thích hợp. Tôi không hoàn toàn tăng tốc với phiên bản mới nhất của công việc của Joe - anh ấy chỉ nói với tôi về phiên bản đầu tiên, chứ không phải phiên bản mới nhất, nhưng dù sao, nếu bạn theo dõi phân bổ bộ nhớ trong nền tảng của Ruby, bạn đang theo dõi địa chỉ đối tượng chứa bất kỳ thứ gì bạn đang phân bổ.

Điều đó không có nghĩa là bạn có thể coi trọng địa chỉ và đọc giá trị dữ liệu bạn mong muốn tìm thấy tại địa chỉ đó. Dereferencing địa chỉ sẽ trỏ bạn đến bên trong của một đối tượng Ruby cơ bản. Đối tượng Ruby là một đối tượng cơ bản, sau đó lưu trữ dữ liệu bổ sung cùng với, vì vậy việc biết địa chỉ thực sự không hữu ích lắm trừ khi bạn đang viết một công cụ như Ruby Memory Validator hoặc memprof.

Làm thế nào để tôi biết được điều này về Ruby Memory Validator và API mà chúng tôi đã phát hành? Tôi đã thiết kế Ruby Memory Validator. Tôi cũng đã viết các bit ngôn ngữ lắp ráp chặn các cuộc gọi Ruby phân bổ bộ nhớ.

0

Kể từ khi bạn đã chỉ rõ (chôn trong một chú thích ở đâu đó) mà bạn đang thực sự chỉ cố gắng để hiểu làm thế nào của Ruby tham chiếu điều, tôi nghĩ mọi thứ làm việc như sau:

Một VALUE trong C api Ruby tượng trưng cho một đối tượng (một nil, số FixNum hoặc Boolean) hoặc trỏ đến số Object. Các VALUE chứa một thẻ 3 bit chỉ ra đó là những gì nó, và có giá trị (cho 3 đầu tiên) hoặc một con trỏ bộ nhớ trực tiếp (cho một Object). Không có cách nào để truy cập trực tiếp vào số VALUE trong Ruby, (Tôi không chắc chắn nếu số object_id giống nhau hay khác nhau.)

Lưu ý rằng JRuby hoạt động khác nhau.

9

Có.

Từ "Fiddling with Ruby’s Fiddle":.

"Bạn có thể nhận được giá trị con trỏ thực tế của một đối tượng bằng cách lấy đối tượng id, và làm một sự thay đổi Bitwise sang trái này sẽ cung cấp cho bạn con trỏ (hoặc bộ nhớ vị trí) của đối tượng ruby ​​trong bộ nhớ. "

Sử dụng ví dụ của bạn của i = 5 nó có thể được thực hiện như sau:

i = 5 
i_ptr_int = i.object_id << 1 
=> 22 

"In Ruby, why does inspect() print out some kind of object id which is different from what object_id() gives?" có thêm thông tin về object_id, bao gồm một giới thiệu ngắn gọn về nguồn C là cơ sở để thực hiện mà bạn có thể tìm thấy hữu ích .

Hãy xem "Fiddle" để biết một số điều thú vị khác bạn có thể làm.

+0

Không chắc tại sao câu trả lời này không được bỏ phiếu nhiều hơn, điều này sẽ giúp ích rất nhiều! Nếu bạn có 'foo = Class.new' thì' foo.to_s' trả về một cái gì đó như "# ". Nhìn vào mã nguồn Ruby, chuỗi này được gán cho @tmp_classpath. Tuy nhiên, khi bạn gán đối tượng này cho một hằng số, 'Foo = foo',' foo.to_s' trả về "Foo" và @tmp_classpath sẽ bị xóa. Tôi có thông báo gỡ lỗi cả trước và sau khi gán liên tục, và bây giờ có thể sử dụng '(foo.object_id << 1) .to_s (16)' để ghép các thông báo này lên. – fastryan

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