| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Java: Общие вопросы > Тест на OutOfMemoryError |
| Автор: MisterCleric 4.6.2009, 15:42 | ||
Привет всем. Кто что может сказать по данному поводу? Получил такой вопрос на собеседовании
Если раскоментировать int i=1;, то OutOfMemoryError не будет. |
| Автор: math64 4.6.2009, 15:57 |
| А врде так и так OutOfMemoryError не должно быть: при выделении второго data первый уже вне зоны видимости и может быть удалён сборщиком мусора. |
| Автор: hvzh 4.6.2009, 16:00 |
| Судя по коду строка System.out.println("No OutOfMemoryError"); будет выполняться всегда. Кстати, одна скобка в коде явно лишняя |
| Автор: COVD 4.6.2009, 16:07 |
| Держитесь подальше от придумывающих такие тесты - у них, похоже, нет реальных дел. |
| Автор: MisterCleric 4.6.2009, 16:07 |
| Вот код от сюда http://www.javaspecialists.eu/archive/Issue173.html |
| Автор: COVD 4.6.2009, 16:18 |
| Я проверял, компилятор это пропускает и все так , как вы описываете. Но я в первый раз вижу такую конструкцию (скобки внутри скобок). Наверное, это нормально для олимпиады по программированию, но на практике такое я точно использовать никогда не буду. Проще надо. |
| Автор: MisterCleric 4.6.2009, 16:20 |
| понятно. Но вопрос заключался в том, почему после того, как мы раскоментируем объявление переменной, GC освобождает память, если нет, то вылазит знаменитый Exception |
| Автор: hvzh 4.6.2009, 16:49 | ||
| Нда... Интересно... Можно предположить, что при первом аллоцировании heap исчерпывается на 60% так что на второе памяти просто не хватает. Также следует отметить, что это аллоцирование происходит в своей области видимости и, следовательно, в момент второго аллоцирования память должна быть освобождена. Но вот почему это освобождение происходит только после объявления какой-либо переменной типа int i = 0; я тупо не знаю. Кстати, если код изменить следующим образом
то ошибка выделения памяти будет генериться в любом случае |
| Автор: MisterCleric 4.6.2009, 16:56 | ||
ага. Потому, что GC еще не считает byte[] data = new byte[dataSize]; уже недостижимой ссылкой. А вот почему он в исходном случае не считает ее такой, эт уже вопрос... |
| Автор: COVD 4.6.2009, 17:06 |
| Если пофантазировать, то получается, что локальная переменная (byte[] data во внутренних скобках) выбрасывается из стека (и, следовательно, становится доступной для GC) при добавлении чего-то в стек. Это происходит, например, при выполнении строки int i=1; . Если же выполняется сразу byte[] data = new byte[dataSize]; , то тут сначала делается попытка выделить память (а локальная переменная все еще в стеке) , что и приводит к исключению. Наверное, это полезно знать и доктор Ханс этим примером показывает, почему надежнее обнулять переменные. Но все же на мой взгляд это академический нюанс. |
| Автор: Fieral 4.6.2009, 18:04 | ||
| внутренние скобки позволяют ограничить область видимости переменной - иногда это удобно использовать. например так:
возможно это потомучто счетчик ссылок делает "i--" на выходе из scope (из зоны между скобками) |
| Автор: MisterCleric 5.6.2009, 09:48 | ||
| Ну что ж: всем спасибо за участие в разборе такого вот интересного вопроса с памятью. Я тоже так думаю, что COVD где-то прав. Думаю можно ему дать плюсик за понимаение
а мы будем ждать пояснений от доктора Ханса в следующем номере.... |