Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.139.62.103] |
|
Сообщ.
#1
,
|
|
|
Народ, не подскажите ссылки про сборщик мусора почитать. Желательно на русском.
а вопрос во какой - если мы создаем экземпляр класса, в котором есть еще объекты, а потом делаем ссылку на этот экземпляр равнуюю null - то сборщик полностью очищает память или нужно принудительно еще обнулять ссылку на внутренние объекты? Или все же достаточно сделать instance=null; ? |
Сообщ.
#2
,
|
|
|
Цитата bit_immo @ Или все же достаточно сделать instance=null; Достаточно, если у тебя нигде не осталось прямых линков на внутренние объекты. Добавлено А вообще, если не ошибаюсь, объект удаляется тогда, когда на него не остается ссылок ни в одном из запущенных потоков программы. |
Сообщ.
#3
,
|
|
|
и, если в методе мы создали объект - после выполнения метода - ссылки на объекты в методе тоже не нужно обнулять (сборщик сам убирает)?
|
Сообщ.
#4
,
|
|
|
Цитата bit_immo @ и, если в методе мы создали объект - после выполнения метода - ссылки на объекты в методе тоже не нужно обнулять (сборщик сам убирает)? Именно так. Вообще, я и сам не знаю механизма сборки мусора. Вот, например, есть такой код: class ClassOne { private ClassTwo secondObj = new ClassTwo(); public void changeArray(ArrayList al) { al.add(secondObj); } } public class MainClass { public static void main(String args) { ArrayList list = new ArrayList(); ClassOne firstObj = new ClassOne(); firstObj.changeArray(list); .... // в остальном коде нет ссылок на firstObj, // но есть ссылки на list } } Думаю, в таком варианте secondObj останется неубранным. А вот насчет firstObj - не знаю. Кто-нибудь может подсказать? |
Сообщ.
#5
,
|
|
|
в общем ладно - накидал я тест для проверки
Если запустить так - то будет все нормально вечный цикл будет постоянно заполнять вектор. Но если закоментировать метод destroy - то произойдет Out Of Memory. if (i == 18000) { - 18000 возможно прийдеться подобрать вручную (это на моем эмуле хватило столько записей - чтобы заполнить память, возможно на других будет heap меньше) Следовательно - можно пойти двумя дорогами: 1. всегда очищать все глобальные ссылки в экземплярах классов (метод destroy). Только глобальные, так как объекты, которые созданые только в методе - память за ними будет очищена после работы метода. Очищать нужно в том числе и int a; => a=null; иначе память все равно останется не доступной 2. принять правило - всегда обнулять ненужные ссылки. ИМХО - 2 ой вариант более геморный - так как запаришся всегда за собой убирать )) в связи с этим вопрос: действительно ли мусорщик убирает всегда (если ссылки на объект не глобальные) после отработки метода или это может происходить не всегда - и нужно всетаки принудильно обнулять ссылки локальные в методе. ????? import javax.microedition.midlet.MIDlet; import javax.microedition.lcdui.*; import java.util.Vector; public class Test2 extends MIDlet { private static Vector v = new Vector(); public void startApp() { Form form = new Form("Test"); Display.getDisplay(this).setCurrent(form); System.out.println("Total memory: " + Runtime.getRuntime().totalMemory()); System.out.println("Free memory: " + Runtime.getRuntime().freeMemory()); Test3 test3 = new Test3(); System.out.println("Total memory: " + Runtime.getRuntime().totalMemory()); System.out.println("Free memory: " + Runtime.getRuntime().freeMemory()); test3.destroy(); test3 = null; while (true) { test(); System.out.println("Total memory: " + Runtime.getRuntime().totalMemory()); System.out.println("Free memory: " + Runtime.getRuntime().freeMemory()); } } public void pauseApp() { } public void destroyApp(boolean destroy) { } public void test() { Vector v = new Vector(); int i = 0; while (true) { if (i == 18000) { break; } v.addElement(new Integer(i)); i++; } } } import java.util.Vector; public class Test3 { private static Vector v = new Vector(); public Test3() { test(); } public void test() { int i = 0; while (true) { if (i == 18000) { break; } v.addElement(new Integer(i)); i++; } } public void destroy() { v = null; } } |
Сообщ.
#6
,
|
|
|
Цитата А вообще, если не ошибаюсь, объект удаляется тогда, когда на него не остается ссылок ни в одном из запущенных потоков программы. По-моему, да... Причём, доступа к "счётчику" извне не существует, если не ошибаюсь. Прога сама должна подчищать за собой. Цитата 1. всегда очищать все глобальные ссылки в экземплярах классов (метод destroy). Только глобальные, так как объекты, которые созданые только в методе - память за ними будет очищена после работы метода. Очищать нужно в том числе и int a; => a=null; иначе память все равно останется не доступной По поводу #1. Этот вариант более легко реализуемый. Более, скажем так, стандартный и, по этой причине, более предпочтительный. Мы же в Java2ME, а всех возможностей Java здесь крайне сложно реализовать. По этой причине, программирование здесь требует большей щепетильности. :D:D:D Программе самой приходится отслеживать состояние её составляющих на уровне внутренней организации программы. Как правило, доступ к составляющим программы извне в Java2ME либо затруднён, либо невозможен. "Общесистемный" (кхммм...) сборщик мусора может сработать только в случае корректного высвобождения ресурсов самой программой, т.к. у него функционал дохленький. Добавлено Цитата А вот насчет firstObj - не знаю. Кто-нибудь может подсказать? Хммм... Проверить бы надо, но, по-моему, в зависимости от "профиля MIDP". В версии 1.0, весьма возможно, останется неубранным. В версии 2.0 -- должен быть убранным. Хотя, я и не утверждаю этого однозначно, но, в принципе, можно проверить... Добавлено Бррррр... По ходу дела, действительно, не хило было бы по-тестировать в разных "окружениях"... |
Сообщ.
#7
,
|
|
|
Цитата the_Shadow @ "Общесистемный" (кхммм...) сборщик мусора может сработать только в случае корректного высвобождения ресурсов самой программой... Вот только когда он ещё сработает Но на то есть void gc();! |
Сообщ.
#8
,
|
|
|
Цитата SVK @ Вот только когда он ещё сработает Но на то есть void gc();! ...который тоже еще неизвестно когда сработает |
Сообщ.
#9
,
|
|
|
Угу... Дело в том, что с Java2ME лучше так не шутить... Проще и, на мой взгляд, умнее, было бы самому обо всём позаботиться... Этакий... "ассемблерный стиль" программирования на Java. :D:D:D
|