Удаление объекта
Есть метод у объекта,которые проверяет вылет за пределы,и если вылетел то должен этот объект удаляться.
Я в java недавно,но явных деструкторов как понял нету.Нашёл про finalize,и написал соответсвующий код
1 2 3 4 5 6 7 8
public void finalize() {}; private void check()
Но объект всё равно не удаляется. Понял это по тому что ссылка на объект по прежнему остаётся не null.
Так как удалить объект в его же методе,в finalize дописать что-то надо?
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:
Удаление объекта
У каждого класса есть метод который удаляет определенный объект. deleteObject(Car car).

Удаление объекта из массива объектов
Здравствуйте. Вопрос вот в чем: есть массив объектов некоторого класса в ArrayList. В определенный.
Удаление объекта при столкновении — ConcurrentModificationException
Выскакивает эта проклятая ошибка. Пытаюсь с помощью итератора пробежаться по коллекции и, если.
любитель покушать
686 / 640 / 248
Регистрация: 25.09.2011
Сообщений: 1,313
http://habrahabr.ru/post/130370/
Вот, почитай
Регистрация: 26.04.2012
Сообщений: 233
Почитал почитал.
В итоге вопрос,а можно ли обратить в классе к ссылке на него же.
То есть например есть объект
Object s = new Object;
а в классе метод Чек,и можно так написать что бы он удалял ссылку на самого себя
что то типо this == null; и ссылка s занулится?
любитель покушать
686 / 640 / 248
Регистрация: 25.09.2011
Сообщений: 1,313
Justix, на сколько я знаю нет, да и бросьте вы это занятие с удалением объектов, за вас это gc сделает
Регистрация: 26.04.2012
Сообщений: 233
Так он сделает после закрытия программы наверное.А пока она не закроет,этих объектов станет куча и следовательно производительность упадётОо
Ну я наверное сделаю проверку тогда не в этом классе а в другом где они и вызываются.
любитель покушать
686 / 640 / 248
Регистрация: 25.09.2011
Сообщений: 1,313
Добавлено через 2 минуты
может замечали, когда при работе с java-приложением, оно так резко начинает работать шустрее, как-будто открылось второе дыхание, так вот в этот момент gc почистил мусор
2586 / 2259 / 257
Регистрация: 14.09.2011
Сообщений: 5,185
Записей в блоге: 18
Сообщение от Justix 
А пока она не закроет,этих объектов станет куча и следовательно производительность упадётОо
Вы бы чтоб не гадать почитали чтоли про типы ссылок Hard, Soft, Weak и Phantom, а потом про то когда объекты становятся доступны для сборщика мусора (видимость ссылки в статическом контексте и тд).
И тогда вам не придётся делать наверное, сможете наверняка
ещё добавлю: представьте себе что в методе finalize(); произошло исключение — угадайте будет удалён объект или нет?
2000 / 1427 / 92
Регистрация: 25.11.2010
Сообщений: 3,611
Сообщение от mutagen 
ещё добавлю: представьте себе что в методе finalize(); произошло исключение — угадайте будет удалён объект или нет?
Заставило задуматься секунд на 5. Будет.
Добавлено через 1 минуту
Сообщение от Justix 
Нашёл про finalize
И забудьте. Надолго. finalize можно использовать только ОЧЕНЬ хорошо понимая, что Вы делаете. У Вас он не делает ничего, кроме как сильно замедляет скорость сборки мусора.
Обнуляйте ссылки на объекты, остальное сделает JVM.
2586 / 2259 / 257
Регистрация: 14.09.2011
Сообщений: 5,185
Записей в блоге: 18
Сообщение от Skipy 
нет не будет, так как этот метод вызывается 1 раз прямо перед удалением и если он фейлится, то объект зависает
2000 / 1427 / 92
Регистрация: 25.11.2010
Сообщений: 3,611
Не факт. Я читал приведенную выше статью, там в комментариях было как раз обсуждение теста этого эффекта. Если брошено исключение — прерывается финализация объекта. Но ссылок на него как не было, так и нет. И я, честно сказать, не вижу причин, почему бы этот объект не был убран в следующий проход. Я бы сказал, тут зависит от сборщика, спецификация этот момент не покрывает.
Я вот это имел в виду: http://habrahabr.ru/post/130370/. И там комментарии:
cheremin,17 августа 2012 в 19:19#
Насчет «зависнет навсегда» — там написано что финализация будет прервана. Насчет сборки ничего не написано. Было бы интересно посмотреть на тест-кейс, где воспроизводится «зависание навсегда»
Nomad1, 17 августа 2012 в 19:30#↵
Действительно, спецификация не утверждает, что сборки не будет, но на практике память не освобождается и рано или поздно нас ждет ООМ. У меня так было в одном проекте и больше всего поразило, что исключение втихую игноририруется. Конечно, может все и от рантайма зависит и тот же OpenJDK этим не страдает.
Вот нашелся эксперимент одного энтузиаста:
elliottback.com/wp/java-memory-leaks-w-finalize-examples/
Думаю, при желании можно и другие найти.
cheremin,17 августа 2012 в 21:05
Если вы внимательно прочитаете комментарии к той статье, вы найдете там разоблачение черной магии: нет никаких утечек, просто выполнение чего-то, достаточно тяжелого в finalize() задерживает очередь финализации, и GC просто не успевает угнаться за аллокацией в быстром цикле. Если основной цикл аллокации чуть затормозить — все освобождается.
Добавлено через 19 минут
Ну вот накидал я простейший тестик.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
package ru.skipy.tests; /** * FinalizeOOMTest * * @author Eugene Matyushkin aka Skipy * @since 25.01.13 */ public class FinalizeOOMTest { private byte[] data = new byte[1024*1024]; // 1Mb @Override protected void finalize() throws Throwable { super.finalize(); throw new Exception("oops!"); } public static void main(String[] args) { long delta = 1000 * 3600; // 1 hour int counter = 0; long start = System.currentTimeMillis(); while (System.currentTimeMillis() start + delta){ create(); counter++; if ((counter % 100) == 0){ System.out.println(counter); } } } static void create(){ FinalizeOOMTest t = new FinalizeOOMTest(); t.getData()[0] = 0; } public byte[] getData() { return data; } }
Каждый экземпляр тащит за собой 1Мб памяти (твердая ссылка). В finalize гарантированно кидается исключение.
Если бы экземпляр при этом зависал — после непродолжительной работы мы имели бы ООМ. Я дожидался 300000 экземпляров. Т.е. это 300Гб памяти. При стандартном выделении и всего 8Г на машине.
Кстати, интересно посмотреть на то, как выводился счетчик. + 600-700 — пауза. Еще + 600-700 — пауза. Имхо, паузы — это GC. Раз в секунду у меня где-то.
Может, я чего не понимаю и ссылки на byte[] как-то собираются, а сами объекты остаются в памяти. Что-то мне кажется, что это менее вероятно, чем сбор объектов целиком.
Добавлено через 8 минут
Подсоединился к тесту через VisualVM — никаких признаков OOM. Классы не накапливаются, память освобождается.
Как удалить объект из ArrayList?
@Etki если бы он удалял из листа класс, это было бы так listDocument.remove(ToDoDocument); , но этот бред невозможен, к счастью.
20 фев 2015 в 13:02
@argamidon, все в ревизиях
20 фев 2015 в 16:43
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
Для поиска элемента, который надо удалить из ArrayList ‘а, используется метод equals . Весьма вероятно, что вы его либо неправильно переопределили, либо его наоборот, вам его нужно переопределить (поскольку базовая имплементация сравнивает ссылки).
А возможно вы пытаетесь удалить элемент, которого в списке вовсе нет.
Покажите полный код, включая ToDoDocument.
Отслеживать
ответ дан 20 фев 2015 в 11:36
25.1k 4 4 золотых знака 45 45 серебряных знаков 81 81 бронзовый знак
эх, не успел. да, тут скорее всего именно в этом дело
20 фев 2015 в 11:37
Спасибо за подсказку, теперь понятно, через что он удаляет. Надо переопределить метод equals.
20 фев 2015 в 11:38
Простите, а что вы подразумеваете, когда говорите что базовая имплементация equals работает медленно? По вашему, сранение двух ссылок — это медленная операция?
20 фев 2015 в 14:10
метод equals НЕ перегружается. Он переопределяется. Не надо путать людей и манипулировать терминами. [на почитай][1] [1]: programmerinterview.com/index.php/java-questions/…
20 фев 2015 в 14:18
если не работает базовая функция, значит у вас объекты разные при сравнении, а точнее их хэш. Следовательно вы сравнивайте разные объекты, а не идентичные. И нечего лезть тут да куда не надо, оставьте в покое equals и проверяйте свой заголовок в итеративном цикле.
Как удалить элемент массива в Java?
В некоторых случаях возникает необходимость в удалении элементов из Java-массива. Однако язык программирования Java не предоставляет для выполнения этой операции прямого метода. Тем не менее ряд способов всё же имеется. О них и поговорим.
Начнём с того, что в обычном массиве удаление осуществляется не очень удобно. То есть мы не можем просто взять и удалить ячейку из Java-массива. Зато можем обнулить значение этой ячейки.
public class Cat < private String name; public Cat(String name) < this.name = name; >public static void main(String[] args) < Cat[] cats = new Cat[3]; cats[0] = new Cat("Том"); cats[1] = new Cat("Вася"); cats[2] = new Cat("Мурка"); cats[1] = null; System.out.println(Arrays.toString(cats)); >@Override public String toString() < return "Cat'; > >[Cat, null, Cat]Итак, мы видим, что кот Вася благополучно обнулился. Однако при выполнении такой операции в Java-массиве остаётся «дыра», поскольку мы удаляем лишь содержимое ячейки, но не саму ячейку. То есть мы получаем пустую ячейку в середине массива, что не есть хорошо.
Что тут можно сделать? Например, переместить эту ячейку в самый конец массива, сдвинув другие элементы к началу:
public static void main(String[] args) < Cat[] cats = new Cat[4]; cats[0] = new Cat("Том"); cats[1] = new Cat("Вася"); cats[2] = new Cat("Мурка"); cats[3] = new Cat("Барсик"); cats[1] = null; for (int i = 2; i < cats.length-1; i++) < //выполняем перемещение элементов к началу, в результате чего пустая ячейка окажется в конце cats[i-1] = cats[i]; cats[i] = null; >System.out.println(Arrays.toString(cats)); >[Cat, Cat, Cat, null]Всё стало лучше, но, согласитесь, такое решение сложно назвать стабильным. Хотя бы потому, что каждый раз, когда нам надо будет удалить элемент из массива, нам придётся повторять вышеописанную операцию.
Использование ArrayList
Если гора не идёт к Магомету, Магомет идёт к горе. Если мы не можем удалить элемент в обычном массиве, мы можем преобразовать массив в структуру, позволяющую удалять элементы. А потом преобразовать эту структуру обратно в массив.
Выполнить вышеописанную схему нам поможет java.util.List или ArrayList. Дело в том, что в ArrayList реализован специальный метод, позволяющий удалять элементы — remove. В общем виде всё выглядит так:
String[] array = new String[]; List list = new ArrayList<>(Arrays.asList(array)); list.remove("foo"); // Creates a new array with the same size as the list and copies the list // elements to it. array = list.toArray(new String[list.size()]); System.out.println(Arrays.toString(array)); //[bar, baz]Давайте теперь рассмотрим работу метода remove на наших котах:
public static void main(String[] args) < ArrayListcats = new ArrayList<>(); Cat tom = new Cat("Том"); Cat vasya = new Cat("Вася"); Cat murka = new Cat("Мурка"); Cat barsik = new Cat("Барсик"); cats.add(tom); cats.add(vasya); cats.add(murka); cats.add(barsik); System.out.println(cats.toString()); cats.remove(1); System.out.println(cats.toString()); >Итак, мы передали в метод индекс нашего объекта, в результате чего он был удален.
Тут следует отметить следующие особенности метода remove() : — он не оставляет так называемых «дыр» — в нём реализована логика сдвига элементов, если мы удаляем элемент из середины. Вот вывод предыдущего кода:
[Cat, Cat, Cat, Cat] [Cat, Cat, Cat]То есть после удаления одного кота, остальные были передвинуты, и пробелов не осталось.
Кроме того, remove способен удалять объект не только по индексу, но и по ссылке:
public static void main(String[] args) < ArrayListcats = new ArrayList<>(); Cat tom = new Cat("Том"); Cat vasya = new Cat("Вася"); Cat murka = new Cat("Мурка"); Cat barsik = new Cat("Барсик"); cats.add(tom); cats.add(vasya); cats.add(murka); cats.add(barsik); System.out.println(cats.toString()); cats.remove(murka); System.out.println(cats.toString()); >[Cat, Cat, Cat, Cat] [Cat, Cat, Cat]Однако на просторах сети можно найти и другие способы удаления нужных элементов из массива.
Используем System.arraycopy
Мы можем просто создать копию исходного массива с помощью System.arraycopy(), удалив таким нехитрым способом соответствующий элемент:
int[] array = new int[] < 1, 2, 3, 4 >; // Original array. int[] result = new int[array.length - 1]; // Array which will contain the result. int index = 1; // Remove the value "2". // Copy the elements at the left of the index. System.arraycopy(array, 0, result, 0, index); // Copy the elements at the right of the index. System.arraycopy(array, index + 1, result, index, array.length - index - 1); System.out.println(Arrays.toString(result)); //[1, 3, 4]Используем Apache Commons Lang
Последний способ, о котором стоит упомянуть, — применение библиотеки Apache Commons Lang и статического метода removeElement() класса ArrayUtils:
int[] array = new int[]; array = ArrayUtils.removeElement(array, 2); //remove first occurrence of 2 System.out.println(Arrays.toString(array)); //[1, 3, 4]Apache Commons предоставляет нам библиотеку с именем org.apache.commons.lang3. Добавить библиотеку в ваш проект можно с помощью следующей maven-зависимости:
org.apache.commons commons-lang3 3.0 Данный пакет предоставляет класс ArrayUtils. Используя метод remove() этого класса, можно удалять элементы. Рассмотрим это на примере удаления повторяющихся элементов в массиве Java. Для обнаружения дублей надо сравнить каждый элемент Java-массива с оставшимися, для чего можно использовать 2 вложенных цикла.
import java.util.Arrays; import java.util.Scanner; import org.apache.commons.lang3.ArrayUtils; public class DeleteDuplicate < public static void main(String args[]) < Scanner sc = new Scanner(System.in); System.out.println("Enter the size of the array that is to be created::"); int size = sc.nextInt(); int[] myArray = new int[size]; System.out.println("Enter the elements of the array ::"); for(int i=0; iSystem.out.println("The array created is ::"+Arrays.toString(myArray)); for(int i=0; i > > System.out.println("Array after removing elements ::"+Arrays.toString(myArray)); > >Вот, как это будет работать:
Enter the size of the array that is to be created :: 6 Enter the elements of the array :: 232 232 65 47 89 42 The array created is :: [232, 232, 65, 47, 89, 42] Array after removing elements :: [232, 65, 47, 89, 42]На этом всё, надеемся, предоставленная информация была полезной!
Как удалить обьект в Java
Java - язык с автоматическим управлением памятью. Поэтому явно вручную освободить память, выделенную для объекта, нельзя.
Вы можете удалить объект из коллекции bullets :
bullets.remove(bullet);и тогда, если на него не осталось других ссылок, сборщик мусора когда-нибудь почистит его.
Если пуль много, и они появляются и исчезают очень часто, вы можете захотеть держать конечное количество пуль всегда в памяти в некотором пуле (коллекции) и добавить им поле boolean active . После этого вместо создания новой пули - брать из пула любую неактивную пулю и выставлять ей active = true . Когда пуля должна быть удалена - сбрасывать поле active в false .