Почему Java не имеет никакого деструктора как C++? [закрытый]

7
задан Abhishek Jain 9 April 2010 в 10:55
поделиться

7 ответов

Если вы знаете, что больше не знаете какие-то большие объекты, просто установите для ссылок на них значение null. Это могло бы ускорить сборку мусора этих объектов.

1
ответ дан 6 December 2019 в 04:44
поделиться

Деструктор C ++ - это не способ уничтожения объектов - это набор операций, которые должны выполняться при разрушении объекта.

Думаю, вы сбиваете с толку терминологию. Вот как я это вижу:

создать объект = сначала выделить память, затем построить через конструктор

уничтожить объект = сначала уничтожить через деструктор, затем освободите память

От того, как выделяется и освобождается память, зависит. Если вы используете new и delete , управление памятью выполняется с помощью void * operator new (size_t) и void operator delete (void *) .

1
ответ дан 6 December 2019 в 04:44
поделиться

Деструктор C++ не является способом уничтожения объектов - это набор операций, которые должны быть выполнены при уничтожении объекта. В Java вы не можете контролировать время уничтожения объектов (они могут даже никогда не уничтожаться), поэтому крайне не рекомендуется помещать любой важный код, который будет выполняться при уничтожении объекта (хотя это возможно - метод finalize). Если вы просите не деструктор, а способ явного уничтожения данного объекта, вы приглашаете висячие ссылки в свой код. Они не приветствуются.

7
ответ дан 6 December 2019 в 04:44
поделиться

Это делает разработчика Java ленивым в реализации управления памятью.

Нет, это освобождает их для выполнения полезной работы.

А сборка мусора очень дорого.

По сравнению с чем? С фактами? Цифрами? Вы устарели лет на 20 с этим замечанием. Одно только распространение Java эффективно опровергает это утверждение.

Это может улучшить производительность приложений.

Или нет. У вас есть какие-то факты, которые можно привести?

Тогда почему бы не дать им возможность уничтожать объекты?

Потому что это не требуется?

5
ответ дан 6 December 2019 в 04:44
поделиться

Вы утверждаете, что "сборка мусора очень дорога" - не могли бы вы подкрепить это доказательствами? Сборка мусора, конечно, не является бесплатной, но современные сборщики мусора очень хороши.

Обратите внимание, что один из способов, с помощью которого GC может быть эффективным, заключается в том, что он знает, что он единственный, кто выполняет выделение и удаление памяти (для управляемых объектов). Разрешение разработчику явно освобождать объект может помешать этой эффективности. Вам также нужно будет побеспокоиться о том, что произойдет, если разработчик попытается "использовать" освобожденный объект:

Foo f = new Foo();
Foo g = f;
free(f); // Or whatever
System.out.println(g.toString()); // What should this do?

Вы предлагаете, чтобы каждый объект имел дополнительный флаг "был ли он явно освобожден", который нужно проверять при каждом разыменовании? Честно говоря, это похоже на рецепт катастрофы.

Однако вы правы - это позволяет разработчикам Java быть ленивыми в этой области . Это хорошо. IDE тоже позволяют разработчикам быть ленивыми - как и языки высокого уровня и т.д. Лень в распределении памяти позволяет разработчикам в управляемых средах тратить свою энергию, беспокоясь о проблемах бизнеса, а не об управлении памятью.

55
ответ дан 6 December 2019 в 04:44
поделиться

Сборка мусора - очень дорогое удовольствие.

Фактически, для сложных приложений производительность сборки мусора конкурирует с ручным управлением хранилищем на основе malloc / free . Это наглядно демонстрирует классическая статья Бенджамина Цорна . В этой статье Цорн описывает, как он модифицировал некоторые приложения с большим объемом кучи, чтобы использовать консервативный сборщик мусора вместо malloc и free . Затем он проверил исходную и модифицированную версии приложений. Результатом была сопоставимая производительность.

Этот документ был опубликован в журнале Software Practice and Experience в 1993 году. Если вы не читали его, вы не имеете права делать заявления о «неэффективности» сборки мусора.

Обратите внимание, что это исследование проводилось с использованием консервативного сборщика мусора 1993 года выпуска . Консервативный коллектор - это разметка без уплотнения; т.е. объекты, не являющиеся мусорными, не перемещаются. Последнее означает, что выделение места для новых объектов происходит так же медленно и сложно, как malloc . Напротив, современные сборщики мусора (например,Java 6/7) являются гораздо более эффективными сборщиками копирования поколений. А поскольку копирование сжимает оставшиеся объекты, не являющиеся мусорными, распределение выполняется намного быстрее. Это делает GC еще более конкурентоспособным ... если бы можно было найти способ провести сравнение.


Разработчик не контролирует сборщик мусора, но может управлять или создавать объект. Тогда почему бы не дать им возможность разрушать объекты?

Это зависит от того, что именно вы подразумеваете под «разрушением».

  • В Java у вас есть возможность присвоить null . В некоторых случаях это может ускорить разрушение объекта.

  • В Java вы можете использовать финализаторы и ссылочные типы, чтобы заметить, что объект вот-вот будет уничтожен ... и так кое-что об этом.

  • В Java вы можете определить метод close () (или эквивалентный) для любого объекта и заставить его делать что-нибудь подходящее. Затем назовите это явно.

  • В Java 7 у вас есть конструкция «попробуйте с ресурсами» для автоматического вызова close () для ресурсов при выходе из области видимости.

Однако вы не можете вызвать удаление объекта Java СЕЙЧАС. Причина, по которой это недопустимо, заключается в том, что это позволит программе создавать висящие ссылки, что может привести к повреждению кучи и случайным сбоям JVM.

Это НЕ способ Java. Философия заключается в том, что написание надежных программ важнее эффективности. Хотя некоторые аспекты Java не следуют этому (например, многопоточность), никому не нужна возможность случайных сбоев JVM.

22
ответ дан 6 December 2019 в 04:44
поделиться

В Java действительно есть возможность контролировать уничтожение объектов. Просто для этого используется другая идиома:

Connection conn = null;
try {
  conn = ...
  // do stuff
} finally {
  try { conn.close(); } catch (Exception e) { }
}

Вы можете указать на то, что это не уничтожение объекта и что вы можете, например, передать этот объект чему-то другому и сохранить ссылку на него. Вы правы по обоим пунктам. Это просто настолько близко, насколько это возможно в Java (и большинстве управляемых платформ).

Но нет, в Java нет, как вы говорите, механизма деструктора, как в C++. Некоторые люди путают финализаторы с этим. Они не являются деструкторами, и использовать их как таковые опасно.

Управление памятью для программиста - сложная задача. Вы можете легко утечь память, особенно при многопоточном программировании (тоже сложно). Опыт показал, что стоимость GC, хотя и реальная и иногда существенная, в подавляющем большинстве случаев вполне оправдывается увеличением производительности и количеством ошибок, поэтому подавляющее большинство платформ сейчас являются "управляемыми" (то есть используют сборку мусора).

-2
ответ дан 6 December 2019 в 04:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: