Общий вопрос: у Java есть куча и локальный стек. Можете ли вы получить доступ к любому объекту из кучи? - PullRequest
15 голосов
/ 14 ноября 2008

Я действительно смотрел на различия между передачей по значению и тем, как Java распределяет объекты, и что делает Java для помещения объектов в стек.

Есть ли в любом случае доступ к объектам, расположенным в куче? Какие механизмы обеспечивает Java, чтобы гарантировать, что правильный метод может получить доступ к нужным данным из кучи?

Кажется, что если вы были хитры и, возможно, даже манипулировали байт-кодом Java во время выполнения, вы могли бы манипулировать данными из кучи, когда вы не должны?

Ответы [ 3 ]

17 голосов
/ 14 ноября 2008

В наборе команд JVM нет инструкции, которая дает произвольный доступ к куче. Следовательно, манипулирование байт-кодом здесь вам не поможет.

В JVM также есть верификатор. Он проверяет код каждого метода (поскольку класс загружается), чтобы убедиться, что метод не пытается извлечь больше значений из стека выполнения, чем то, что он поместил в него. Это гарантирует, что метод не может «видеть» объекты, на которые указывает его вызывающий метод.

Наконец, локальные переменные хранятся в массиве для метода (известный как «массив локальных переменных»). Опять же, верификатор проверяет, что каждая инструкция чтения / записи из / в этот массив указывает индекс, который меньше размера массива. Обратите внимание, что эти инструкции JVM могут указывать только постоянный индекс. Они не могут получить вычисленное значение и использовать его в качестве индекса.

Подводя итог, скажем, нет.

9 голосов
/ 14 ноября 2008

Все объекты в Java расположены в куче. Я не совсем уверен, что вы подразумеваете под "доступ к объектам из кучи". Единственное, что хранится в стеке, это список функций, которые вызваны в текущий контекст, и их локальные переменные и параметры. Все локальные переменные и параметры являются примитивными типами или ссылками.

Если вы выделяете объект, используя new (это единственный способ выделить не примитивные типы; да, это включает типы массивов), тогда объект размещается в куче, а ссылка на этот объект сохраняется в либо стек, либо куча, в зависимости от того, хранится ли ссылка в локальной переменной / параметре или как член другого объекта.

При передаче в качестве параметров функциям все объекты передаются по ссылке - если функция изменяет параметр, исходный объект также изменяется. Аналогично, можно также сказать, что ссылки на объекты передаются по значению - если вы измените параметр для ссылки на новый объект, он будет продолжать ссылаться на этот объект в течение всей функции, но исходный объект, который был передан в все равно будет ссылаться на все, что упоминалось ранее. Примитивные типы также передаются по значению.

4 голосов
/ 14 ноября 2008

Что касается объектов в стеке, то только новая виртуальная машина Java 6 от SUN (и, возможно, некоторых других) будет пытаться оптимизировать байт-код путем помещения объектов в стек. Как правило, все объекты попадут в кучу. Для справки: http://www.ibm.com/developerworks/java/library/j-jtp09275.html

Также спецификация JVM находится на http://java.sun.com/docs/books/jvms/second_edition/html/Overview.doc.html#6348. JVM защищает свою кучу, просто не давая вам инструкции, необходимые для ее повреждения. Недостатки в реализации JVM могут привести к изменению вашего пробега.

...