Общий вопрос: в Java есть куча и локальный стек. Можете ли вы получить доступ к любому объекту из кучи?

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

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

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

Хороший вопрос - если бы я знал больше о java; хороший ответ на это будет началом моего просветления :)

Jarrod Dixon 14.11.2008 06:33
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
15
1
6 472
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

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

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

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

Есть и другие способы выделения новых объектов (клонирование, Class.newInstance (), десериализация), но все они попадают в кучу.

Dave L. 14.11.2008 08:03

Объяснение «можно также сказать, что ссылки на объекты передаются по значению» - единственно верное. Утверждать, что объекты передаются по ссылке, неточно. В основном Java имеет только передачу по значению, как C.

Jon Skeet 14.11.2008 10:11
Ответ принят как подходящий

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

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

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

Итак, напомним, ответ - нет.

Я только что вернулся к этому. Таким образом, в основном структура Java и подобных сборщиков мусора, основанных на стеке языков такова, что вы не можете произвольно обращаться к части кучи, когда у вас нет доступа для этого.

Berlin Brown 16.08.2011 07:00

Что касается объектов в стеке, только новая виртуальная машина 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 ваш пробег может отличаться.

Я не согласен с комментариями Java 6. Новая функция анализа выхода потенциально позволяет JVM избегать создания объектов. Таким образом, примитивные компоненты объекта (int, float, ссылки и т. д.) Оказываются в стеке. Объекты существуют только в куче. Период.

John M 17.11.2008 21:42

Другая страница IBM, ibm.com/developerworks/library/j-jtp01274.html, не согласна с вами, Джон М. Кажется, что Java действительно может размещать объекты в стеке.

Steven Schlansker 30.10.2009 21:40

Другие вопросы по теме