Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Тест на OutOfMemoryError, проблемный кусок кода 
V
    Опции темы
MisterCleric
Дата 4.6.2009, 15:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1043
Регистрация: 16.2.2006
Где: Харьков, Украина

Репутация: 5
Всего: 38



Привет всем. Кто что может сказать по данному поводу? Получил такой вопрос на собеседовании
Код

public class JavaMemoryPuzzlePolite {
    private int dataSize =
            (int) (Runtime.getRuntime().maxMemory() * 0.6);

    public void f() {
        {
            byte[] data = new byte[dataSize];
        }
//         int i=1;
        byte[] data = new byte[dataSize];
    }

    public static void main(String[] args) {
        JavaMemoryPuzzlePolite jmp = new JavaMemoryPuzzlePolite();
        jmp.f();
        System.out.println("No OutOfMemoryError");
    }
}


Если раскоментировать int i=1;, то OutOfMemoryError не будет.


--------------------
ПРИШЕЛ, УВИДЕЛ - ПЕРЕПИСАЛ...
PM MAIL ICQ   Вверх
math64
Дата 4.6.2009, 15:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



А врде так и так OutOfMemoryError не должно быть: при выделении второго data первый уже вне зоны видимости и может быть удалён сборщиком мусора.
PM   Вверх
hvzh
Дата 4.6.2009, 16:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 71
Регистрация: 18.10.2006

Репутация: нет
Всего: 1



Судя по коду строка

System.out.println("No OutOfMemoryError");

будет выполняться всегда.

Кстати, одна скобка в коде явно лишняя
PM MAIL   Вверх
COVD
Дата 4.6.2009, 16:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 26.7.2005

Репутация: 17
Всего: 43



Держитесь подальше от придумывающих такие тесты - у них, похоже, нет реальных дел.  
PM MAIL   Вверх
MisterCleric
Дата 4.6.2009, 16:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1043
Регистрация: 16.2.2006
Где: Харьков, Украина

Репутация: 5
Всего: 38



 smile Ребята. Надо сначала запустить и проверить, а потом уже говорить о том, что там лишнее и как оно выполняется
Вот код от сюда
http://www.javaspecialists.eu/archive/Issue173.html


--------------------
ПРИШЕЛ, УВИДЕЛ - ПЕРЕПИСАЛ...
PM MAIL ICQ   Вверх
COVD
Дата 4.6.2009, 16:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 26.7.2005

Репутация: 17
Всего: 43



Я проверял, компилятор это пропускает и все так , как вы описываете. Но я в первый раз вижу такую конструкцию (скобки внутри скобок). Наверное, это нормально для олимпиады по программированию, но на практике такое я точно использовать никогда не буду. Проще надо.
PM MAIL   Вверх
MisterCleric
Дата 4.6.2009, 16:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1043
Регистрация: 16.2.2006
Где: Харьков, Украина

Репутация: 5
Всего: 38



понятно. Но вопрос заключался в том, почему после того, как мы раскоментируем объявление переменной, GC освобождает память, если нет, то вылазит знаменитый Exception


--------------------
ПРИШЕЛ, УВИДЕЛ - ПЕРЕПИСАЛ...
PM MAIL ICQ   Вверх
hvzh
Дата 4.6.2009, 16:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 71
Регистрация: 18.10.2006

Репутация: нет
Всего: 1



Нда... Интересно...
Можно предположить, что при первом аллоцировании heap исчерпывается на 60% так что на второе памяти просто не хватает. Также следует отметить, что это аллоцирование происходит в своей области видимости и, следовательно, в момент второго аллоцирования память должна быть освобождена. Но вот почему это освобождение происходит только после объявления какой-либо переменной типа int i = 0; я тупо не знаю. Кстати, если код изменить следующим образом

Код

public class JavaMemoryPuzzlePolite {
    private int dataSize =
            (int) (Runtime.getRuntime().maxMemory() * 0.6);

    public void f() {
        byte[] data = new byte[dataSize];
        //         int i=1;
        byte[] data = new byte[dataSize];
    }


то ошибка выделения памяти будет генериться в любом случае
PM MAIL   Вверх
MisterCleric
Дата 4.6.2009, 16:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1043
Регистрация: 16.2.2006
Где: Харьков, Украина

Репутация: 5
Всего: 38



Цитата

то ошибка выделения памяти будет генериться в любом случае 

ага. Потому, что GC еще не считает  byte[] data = new byte[dataSize]; уже недостижимой ссылкой.
А вот почему он в исходном случае не считает ее такой, эт уже вопрос...


--------------------
ПРИШЕЛ, УВИДЕЛ - ПЕРЕПИСАЛ...
PM MAIL ICQ   Вверх
COVD
Дата 4.6.2009, 17:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 26.7.2005

Репутация: 17
Всего: 43



Если пофантазировать, то получается, что локальная переменная (byte[] data во внутренних скобках) выбрасывается из стека (и, следовательно, становится доступной для GC) при добавлении чего-то в стек. Это происходит, например, при выполнении строки  int i=1; . Если же выполняется сразу byte[] data = new byte[dataSize]; , то тут сначала делается попытка выделить память (а локальная переменная все еще в стеке) , что и приводит к исключению. Наверное, это полезно знать и доктор Ханс этим примером показывает, почему надежнее обнулять переменные. Но все же на мой взгляд это академический нюанс.   
 
PM MAIL   Вверх
Fieral
Дата 4.6.2009, 18:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 250
Регистрация: 10.12.2007

Репутация: нет
Всего: 1



внутренние скобки позволяют ограничить область видимости переменной -  иногда это удобно использовать.
например так:

Код

public void do(){
        ArrayList<Cool> A = new ArrayList<Cool>();

        {
            Cool C = new Cool();
            C.setName("N1");
            A.add(C);
        }
        {
            Cool C = new Cool();
            C.setName("N2");
            A.add(C);
        }
        {
            Cool C = new Cool();
            C.setName("N3");
            A.add(C);
        }
}


возможно это потомучто счетчик ссылок делает "i--" на выходе из scope (из зоны между скобками)

Это сообщение отредактировал(а) Fieral - 4.6.2009, 18:07
--------------------
Если собака свернулась калачиком, значит будет дождь, а если сидит выпучив глаза, значит у неё запор.
PM MAIL   Вверх
Kangaroo
Дата 4.6.2009, 23:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


AA - Aussie Animal
****


Профиль
Группа: Участник Клуба
Сообщений: 2042
Регистрация: 7.10.2006
Где: US

Репутация: 21
Всего: 104



Цитата(hvzh @  4.6.2009,  16:49 Найти цитируемый пост)
то ошибка выделения памяти будет генериться в любом случае 

Ага, ошибка компиляции  smile 


Цитата(Fieral @  4.6.2009,  18:04 Найти цитируемый пост)
внутренние скобки позволяют ограничить область видимости переменной -  иногда это удобно использовать.
например так:

Это - удобно ?!   smile 


По сабжу - я думал близко к последнему сообщению COVD. Но это так, наугад.


--------------------
Lost....
PM MAIL MSN   Вверх
MisterCleric
Дата 5.6.2009, 09:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1043
Регистрация: 16.2.2006
Где: Харьков, Украина

Репутация: 5
Всего: 38



Ну что ж: всем спасибо за участие в разборе такого вот интересного вопроса с памятью. Я тоже так думаю, что COVD где-то прав. 
Думаю можно ему дать плюсик за понимаение 
Цитата

академических нюансов

а мы будем ждать пояснений от доктора Ханса в следующем номере....


--------------------
ПРИШЕЛ, УВИДЕЛ - ПЕРЕПИСАЛ...
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0847 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.