2010-03-08 13 views
10

Czy istnieje sposób w Ruby, aby uzyskać adres pamięci obiektów ..Dostęp do adresu pamięci obiektów w rubin ..?

powiedzieć ..

(i = 5) jest to, że można uzyskać adres mem tego obiektu 5 ..

I starali się dostać to przez jakiś czas ..,

Każda odpowiedź będzie bardzo mile widziane ...

dzięki,

Pozdrawiam levirg

+10

Dlaczego? Co próbujesz zrobić? – SLaks

Odpowiedz

3

Nie znam sposobu na podanie dokładnego adresu, ale może szukasz czegoś takiego jak metoda object_id?

Wyciąg z ITS documentation

Zwraca identyfikator całkowitą o obj.
Ta sama liczba zostaną zwrócone do wszystkich połączeń w celu identyfikacji dla danego obiektu, a ma dwie aktywne przedmioty będą dzielić id


przykład:

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

Ruby Memory Validator powinny móc aby to zrobić, ale nie jest za darmo.

Aman Gupta patched Joe Damatos memprof ale wydaje mi się, że jest to work in progress i nigdy nie udało mi się go uruchomić na moim komputerze. Joe ma kilka naprawdę dobrych wiadomości na temat memprof i innych rzeczy o niskim poziomie na jego blog.

Teraz nie jestem pewien, czy naprawdę mogą. Liczby całkowite są przechowywane jako Fixnum, a Fixnum nie jest zwykłym obiektem Ruby, tylko wygląda w ten sposób. Ruby używa sprytnie przyśpieszonej sztuczki z wartością object_id, aby uczynić obiekty nieprzydatne wartościami Fixnum. Liczba ta jest w rzeczywistości przechowywana w samym object_id. Dlatego dwa różne pakiety Fixnum zawierające tę samą wartość mają ten sam numer object_id.

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

object_id z Fixnum jest rzeczywiście stworzony przez nieco przesuwa się w lewo, a następnie ustawiając najmniej znaczącego bitu.

5 jest 0b101 i object_id dla 5 jest 11 i 11 binarnie jest 0b1011.

4711 jest 0b0001001001100111, przesunąć w lewo i ustawić bit i masz 0b0010010011001111 i to jest 9423, która dzieje się object_id dla z powyżej.

This behaviour to prawdopodobnie specyfikacja implementacji, ale nie znam implementacji Ruby, która nie obsługuje w ten sposób pakietu Fixnum.

W Rubim są jeszcze co najmniej trzy najbliższe obiekty, to jest false, true i nil.

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

wydaje się, że memprof jest dobry dla 64-bitów, mój jest 32-bitowy ..... dzięki – levirg

+0

Dzięki, tęskniłem za tym w readme dla memprof. Jestem też na 32-bitowym. Zobacz powyżej, aby dowiedzieć się, w jaki sposób Ruby przechowuje Fixnum. –

+0

to było wspaniałe, nauczyłem się czegoś z tego ... dzięki człowieku .. – levirg

0

Co dokładnie próbujesz zrobić?

Należy pamiętać, że obiekt Ruby nie jest bezpośrednio analogiczny do zmiennej w języku takim jak C lub C++. Na przykład:

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 

nawet przez a i b są oddzielne zmienne, są odniesienia do tych samych danych bazowych i mają taką samą object_id.

Jeśli potrzebujesz adresu adresu zmiennej, prawdopodobnie istnieje łatwiejsze podejście do tego, co próbujesz zrobić.

+0

Chciałem tylko wiedzieć, jak odniesienia do obiektów działają na ruby, więc pomyślałem, że adres będzie przydatny, aby załatwić sprawy ..... jeśli istnieje lepszy sposób, w jaki sposób pls mi pomóc ... dzięki – levirg

+0

Nie powinieneś się martwić o odwoływanie się do obiektu w Ruby. W przeciwieństwie do innych języków, w których można przekazać obiekt po wartości lub przez odniesienie, Ruby obsługuje wszystkie aspekty niskiego poziomu. Wszystko, co powinieneś zrobić, to użyć obiektu i przekazać go tak, jakbyś przechodził przez wartość w C. Aby uzyskać więcej informacji o wewnętrznych składnikach Ruby, zobacz http://www.ruby-doc.org/docs/ ProgramowanieRuby/language.html. – bta

1

Ruby Memory Validator podaje adres pamięci dla obiektu.

Praca Joe Damato (http://timetobleed.com/plugging-ruby-memory-leaks-heapstack-dump-patches-to-help-take-out-the-trash) i (http://timetobleed.com/memprof-a-ruby-level-memory-profiler) jest oparta na pracy Weryfikacja oprogramowania, której celem było stworzenie interfejsu API do kontroli pamięci Ruby (http://www.softwareverify.com/ruby/customBuild/index.html).

Joe opisuje to na swoim blogu. Dlatego też praca Joego powinna również zwracać odpowiednie adresy. Nie jestem w pełni gotowy do pracy z najnowszą wersją pracy Joe - opowiadał mi tylko o pierwszej wersji, nie o najnowszej wersji, ale mimo to, śledząc alokację pamięci w fundamentach Ruby, śledzisz adresy obiektów, które posiadają to, co przydzielasz.

Nie oznacza to, że można usunąć adres i odczytać wartość danych, które można znaleźć pod tym adresem. Odwołanie adresu wskaże ci wnętrze podstawowego obiektu Ruby. Obiekty Ruby są podstawowym obiektem, który następnie przechowuje dodatkowe dane razem, więc znajomość rzeczywistego adresu nie jest zbyt użyteczna, chyba że piszesz narzędzie takie jak Ruby Memory Validator lub memprof.

Skąd mam wiedzieć powyższe informacje o Ruby Memory Validator i API, które wydaliśmy? Zaprojektowałem Ruby Memory Validator. Napisałem także bity języka asemblerowego, które przechwytują połączenia Ruby, które przydzielają pamięć.

0

Ponieważ wskazane (pochowany w komentarzu gdzieś), że jesteś naprawdę tylko próbuje zrozumieć, jak Ruby odwołuje rzeczy, myślę, że wszystko działa następująco:

VALUE w C API Ruby reprezentuje obiekt (a nil, a FixNum lub Boolean) lub wskaźnik do Object. VALUE zawiera 3-bitowy znacznik wskazujący, który z nich jest, i zawiera wartość (dla pierwszych 3) lub bezpośredni wskaźnik pamięci (dla Object). Nie ma sposobu, aby uzyskać dostęp do VALUE bezpośrednio w Ruby (nie jestem pewien, czy object_id jest taki sam lub inny.)

Należy zauważyć, że JRuby działa inaczej.

9

Tak.

Od „Fiddling with Ruby’s Fiddle”:.

„Można uzyskać rzeczywistą wartość wskaźnika obiektu poprzez identyfikator obiektu i robi przesunięcie bitowe w lewo To daje wskaźnik (lub pamięci lokalizację) obiektu ruby ​​w pamięci. "

pośrednictwem swojego przykładem i = 5 to można zrobić tak:

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?” ma więcej informacji o object_id, w tym krótkim wprowadzeniu do źródła C leżących u podstaw realizacji, które mogłyby okazać się przydatne .

Spójrz na "Fiddle", aby uzyskać inne fajne rzeczy, które możesz zrobić.

+0

Nie wiem, dlaczego ta odpowiedź nie jest jeszcze przegłosowana, to ogromnie pomaga! Jeśli masz 'foo = Class.new', to' foo.to_s' zwraca coś w stylu "# ". Patrząc na kod źródłowy Ruby, ten ciąg jest przypisany do @ tmp_classpath. Jednak po przypisaniu tego obiektu do stałej, 'Foo = foo',' foo.to_s' zwraca "Foo", a @tmp_classpath jest usuwany. Mam komunikaty debugowania zarówno przed, jak i po stałym przypisaniu, i mogę teraz użyć '(foo.object_id << 1) .to_s (16)' aby je sparować. – fastryan

Powiązane problemy