[java] Про сборку мусора
Может он его не собирает в первый проход...
Да, вот еще, забыл написать.
Если после внутренних блоков написать что-то типа
int i =1;то все становится в порядке.
То есть такой вот код
public static void main(String[] args) {
Book novel1 = new Book(true);
{
Book novel2 = new Book(true);
}
{
Book novel2 = new Book(true);
}
int i = 1;
System.gc;
}
выдает то, что ожидается: два Error'a
Я еще пробовал несколько уровней вложенности блоков, так там еще хитрее получается.
Я добавил еще в класс Book поле int book_id, чтоб отслеживать, какие именно объекты удаляются.
В общем, такое ощущение, что дело в стеке. Я не знаю, как это все реализовано, в смысле, что происходит со стеком при вложенных блоках.
Погоняйте, кому не лень, разные варианты, особенно со вложенными блоками. Может, кто еще что найдет.
} переводится в, грубо говоря, mov ebp, esp. В смысле, стек поднимается на несколько слов (которые были нужны, чтобы разместить ссылки (указатели) на экземпляры Book в куче). И пока ты не затёр эти ссылки своим int i; (т. е. sub esp, 4 для gc они всё ещё легитимны, как ни странно.
Советую поварьировать количество Book-ов и количество int-ов, чтобы убедиться.
Кстати, повторный вызов System.gc никакого эффекта не даёт.
И пока ты не затёр эти ссылки своим int i; (т. е. sub esp, 4 для gc они всё ещё легитимны, как ни странно.Да, я про это подумал. Типа "ленится"?
Советую поварьировать количество Book-ов и количество int-ов, чтобы убедиться.Можно по-подробнее? У меня, например, int i=1 работает на любом числе Book-ов.
> Можно по-подробнее? У меня, например, int i=1 работает на любом числе Book-ов.
class Book {
int i = 0;
Book(int i) { this.i = i; }
public void finalize {
System.out.println("finalize " + i);
}
}
public class Test {
public static void main(String[] args)
{
Book novel = new Book(1);
{
Book n1 = new Book(2);
Book n2 = new Book(3);
Book n3 = new Book(4);
}
int i = 1;
//int j = 2;
//int k = 6;
System.gc;
}
}
Может, из объекта в куче есть обратная ссылка на указатель стекаКак это?
и в области куче, в которой расположен этот экземпляр MyClass, есть компонента - указатель на obj (так сказать, &obj). Но это всё из области догадок.
MyClass obj = new MyClass;
Объект ведь дольще живет, чем этот фрейм стэка (так сказать).
Попробуй сам.
web page
В общем, похоже, что всё так и есть и на сайте Сана про это написано. NOTE: The im object is set to null because there is no gurantee the stack slot occupied by it will be cleared when it goes out of scope. A later method invocation whose stack frame contains the slot previously occupied by im might not put a new value there, in which case, the garbage collector still considers the slot to contain a root.Там рядом с NOTE рассматривают мягкие ссылки, но это, похоже, применимо и для обычных.
This is a problem even with non-conservative exact collectors. As a precaution, you can increase the probability that an object will become softly, weakly, finalizable, or phantomly reachable by clearing variables that refer to it.
Да, похоже, вопрос снят.
"Whenever possible try to explicitly discard an instance by setting it to null. This can sometimes be a useful hint to the garbage collector."
Прям как сговорились все.
Оставить комментарий
olga1969
И опять пример из Брюса Экеля. Про сборку мусора. Вот кодС этим все ясно. В общем, насильственная сборка мусора.
Поменяем немного main:
В общем, по идее, должен выдаваться Error: checked out на объект, создаваемый во внутреннем блоке, поскольку он становится "висячим", так как novel1 выходит из области видимости, когда вызывается gc.
Если написать
то выдается Error: checked out только на один внутренний объект (на который указывала novel1).
Соответственно, если поставить три внутренних блока, то Error выдастся только на первые два.
Куда последный внутренний объект девается? Почему gc его не "видит", не распознает как мусор?