2008-11-14 14 views
14

Naprawdę przyglądałem się różnicom między przekazywaniem przez wartość i tym, jak Java przydziela obiekty i co robi java, aby umieścić obiekty na stosie.Pytanie ogólne: Java ma stertę i stos lokalny. Czy możesz uzyskać dostęp do dowolnego obiektu ze sterty?

Czy istnieje dostęp do obiektów przydzielonych do sterty? Jakie mechanizmy są wymuszane przez java, aby zagwarantować, że właściwa metoda może uzyskać dostęp do właściwych danych poza stosem?

Wygląda na to, że gdybyś był przebiegły, a może nawet manipulował kodem java podczas działania, mógłbyś manipulować danymi poza stosem, kiedy nie powinieneś?

+1

Dobre pytanie - chciałbym wiedzieć więcej o java; dobra odpowiedź na to będzie początkiem mojego oświecenia :) –

Odpowiedz

17

Brak instrukcji w zestawie instrukcji JVM, który zapewnia arbitralny dostęp do sterty. Dlatego manipulacja kodami bajtowymi nie pomoże ci tutaj.

Maszyna JVM ma również weryfikatora. Sprawdza kod każdej metody (podczas ładowania klasy), aby sprawdzić, czy metoda nie próbuje pobrać więcej wartości ze stosu wykonawczego niż to, co na nią wepchnął. Zapewnia to, że metoda nie może "zobaczyć" obiektów wskazywanych przez jego metodę wywołania.

Wreszcie, zmienne lokalne są przechowywane w tablicy dla każdej metody (znanej jako "tablica zmiennych lokalnych"). Ponownie, weryfikator upewnia się, że każda instrukcja odczytu/zapisu od/do tej tablicy określa indeks, który jest mniejszy niż rozmiar tablicy. Zauważ, że te instrukcje maszyny JVM mogą określać tylko stały indeks. Nie mogą przyjąć wartości obliczonej i użyć jej jako indeksu.

Przypomnę więc, odpowiedź brzmi: Nie.

+0

Właśnie wróciłem do tego. Tak więc struktura Java i podobnych narzędzi do zbierania śmieci, opartych na stosie, jest taka, że ​​nie można uzyskać dowolnego dostępu do części sterty, gdy nie ma się do niej dostępu. –

9

Wszystkie obiekty w Javie znajdują się na stercie. Nie jestem do końca pewien, co masz na myśli przez "obiekty dostępu z kupy". Jedyne rzeczy przechowywane na stosie to lista funkcji, które wywołały bieżący kontekst oraz ich lokalne zmienne i parametry. Wszystkie zmienne lokalne i parametry są typami pierwotnymi lub referencjami.

Jeśli przydzielisz obiekt przy użyciu new (który jest jedynym sposobem przydzielania typów niepochodzących), tak, że obejmuje to typy tablic), obiekt jest przydzielany do sterty, a odniesienie do tego obiektu jest przechowywane stos lub stertę, w zależności od tego, czy odniesienie jest przechowywane w zmiennej lokalnej/parametrze lub jako element innego obiektu.

Po przekazaniu parametrów do funkcji wszystkie obiekty są przekazywane przez odniesienie - jeśli funkcja modyfikuje parametr, oryginalny obiekt jest również modyfikowany. Identycznie można również powiedzieć, że odniesienia do obiektu są przekazywane przez wartość - jeśli zmienisz parametr, aby odnosił się do nowego obiektu, będzie on nadal odnosił się do tego obiektu przez czas trwania funkcji, ale do oryginalnego obiektu, który został przekazany nadal będzie odnosić się do tego, o czym wcześniej wspomniało. Typy prymitywne są również przekazywane przez wartość.

+0

Istnieją inne sposoby przydzielania nowych obiektów (klon, Class.newInstance(), deserializacja), ale wszystkie one kończą się na stercie. –

+4

"Można również powiedzieć, że odniesienia do obiektów są przekazywane przez wartość" wyjaśnienie jest jedyną dokładną.Mówienie, że obiekty są przekazywane przez odniesienie, jest niedokładne. Zasadniczo Java ma tylko wartość "pass-by-value", np. C. –

4

Odnośnie obiektów na stosie, to tylko nowa Java 6 VM od Słońca (a może i kilka innych), które starają się zoptymalizować kod bajtowy poprzez umieszczenie obiektów na stos. Zazwyczaj wszystkie obiekty zostaną umieszczone w stercie. Dla porównania sprawdź: http://www.ibm.com/developerworks/java/library/j-jtp09275.html

Również specyfikacja JVM znajduje się pod numerem http://java.sun.com/docs/books/jvms/second_edition/html/Overview.doc.html#6348. JVM chroni swoją stertę, po prostu nie dając instrukcji potrzebnych do jej uszkodzenia. Luki w implementacjach JVM mogą powodować różny przebieg.

+0

Nie zgadzam się z komentarzami Java 6. Nowa funkcja analizy ucieczki potencjalnie pozwala JVM uniknąć tworzenia obiektów. Tak więc prymitywne składniki tego, co byłoby obiektem (int, float, reference, itp.), Kończą się na stosie. Obiekty istnieją tylko w stercie. Kropka. –

+1

Inna strona IBM, http://www.ibm.com/developerworks/library/j-jtp01274.html, nie zgadza się z tobą John M. Wygląda na to, że Java może rzeczywiście przydzielać obiekty na stosie. –

+0

@StevenSchlansker link down .. – Pacerier

Powiązane problemy