Почему делают Вы не явно звоните, завершают () или запускают сборщик "мусора"?

Я получаю ошибку в другой ситуации, и вот проблема и решение:

У меня есть 2 класса, полученные из одного базового класса с именем LevledItem:

public partial class Team : LeveledItem
{
   //Everything is ok here!
}
public partial class Story : LeveledItem
{
   //Everything is ok here!
}

Но в своем DbContext я скопировал некоторый код, но забыл изменить одно из имени класса:

public class MFCTeamDbContext : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        //Other codes here
        modelBuilder.Entity<LeveledItem>()
            .Map<Team>(m => m.Requires("Type").HasValue(ItemType.Team));
    }

public class ProductBacklogDbContext : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        //Other codes here
        modelBuilder.Entity<LeveledItem>()
            .Map<Team>(m => m.Requires("Type").HasValue(ItemType.Story));
    }

Да, вторая карта & lt; Команда> должна быть Map & lt; История>. И это стоило мне полдня, чтобы понять это!

28
задан Community 23 May 2017 в 12:13
поделиться

6 ответов

Короткий ответ: сборка "мусора" Java является очень точно настроенным инструментом. System.gc () является кувалдой.

"куча" Java разделена на различные поколения, каждое из которых собрано с помощью различной стратегии. При присоединении профилировщика к здоровому приложению Вы будете видеть, что оно очень редко должно выполнять самые дорогие виды наборов, потому что большинство объектов поймано более быстрым коллектором копирования в молодом поколении.

Вызов System.gc () непосредственно, в то время как технически не гарантируемый сделать что-либо, на практике инициирует дорогое, stop-world полный набор "кучи". Это почти всегда неправильный поступок . Вы думаете, что сохраняете ресурсы, но Вы на самом деле тратите впустую их ни на каком серьезном основании, вынуждая Java перепроверить все Ваши живые объекты “just в case”.

, Если у Вас есть проблемы с паузами GC в течение критических моментов, Вы - более обеспеченное конфигурирование JVM для использования параллельного коллектора метки/развертки, который был специально разработан для уменьшения времени, проведенного приостановленный, чем попытка взять кувалду к проблеме и просто повреждению его далее.

документ Sun, о котором Вы думали, здесь: Java SE 6 HotSpot™ Сборка "мусора" Виртуальной машины, Настраивающаяся

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

43
ответ дан Charles Miller 28 November 2019 в 03:10
поделиться

Не беспокойтесь финализаторами.

Переключатель к возрастающей сборке "мусора".

, Если Вы хотите помочь сборщику "мусора", пустому указателю от ссылок на объекты, Вам больше не нужно. Меньше пути для следования = более явно мусор.

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

В очень связанной вене при использовании сериализации, и Вы сериализировали временные объекты, Вы собираетесь должны очистить кэши сериализации путем вызова ObjectOutputStream.reset (), или процесс пропустит память и в конечном счете умрет. Оборотная сторона - то, что невременные объекты собираются быть повторно сериализированными. Сериализация временных объектов результата может быть немного более грязной, чем Вы могли бы думать!

Рассматривают использование мягких ссылок. Если Вы не знаете, каковы мягкие ссылки являются, имеют чтение javadoc для java.lang.ref. SoftReference

Избегает Фантомных ссылок и Слабых ссылок, если Вы действительно не становитесь легковозбудимыми.

Наконец, если Вы действительно не можете терпеть GC, используют Java В реальном времени.

нет, я не шучу.

ссылочная реализация является бесплатной загрузить, и книга Peter Dibbles от SUN является действительно хорошим чтением.

4
ответ дан Tim Williscroft 28 November 2019 в 03:10
поделиться

Насколько финализаторы идут:

  1. Они фактически бесполезны. Их, как гарантируют, не назовут своевременно, или действительно, вообще (если GC никогда не будет работать, ни один не будет никакие финализаторы). Это означает, что Вы обычно не должны полагаться на них.
  2. Финализаторы, как гарантируют, не будут идемпотентом. Сборщик "мусора" проявляет большую заботу, чтобы гарантировать, что это никогда не будет звонить finalize() несколько раз на том же объекте. С правильно написанными объектами это не будет иметь значения, но с плохо записанными объектами, вызов завершают, многократно может вызвать проблемы (например, удвоиться, выпуск собственного ресурса... отказывают).
  3. Каждый объект, который имеет finalize() метод, должен также обеспечить close() (или подобный) метод. Это - функция, которую необходимо вызывать. например, FileInputStream.close(). Нет никакой причины звонить finalize(), когда у Вас есть более соответствующий метод, который является , намеревался быть названным Вами.
4
ответ дан Derek Park 28 November 2019 в 03:10
поделиться

Принимающие финализаторы подобны своему тезке.NET тогда, только действительно необходимо назвать их, когда у Вас есть ресурсы, такие как дескрипторы файлов, которые могут просочиться. Большую часть времени Ваши объекты не имеют этих ссылок, таким образом, их не должны называть.

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

, Если Вы знали больше о том, что GC содержал внутренне тогда, Вы могли бы быть в состоянии сделать больше обоснованных решений, но тогда Вы пропустили преимущества GC.

1
ответ дан Brian Lyttle 28 November 2019 в 03:10
поделиться

GC делает большую оптимизацию на том, когда правильно завершить вещи.

Поэтому, если Вы не знакомы с тем, как GC на самом деле работает и как он отмечает поколения, вручную вызов завершает или запускается, GC'ing, вероятно, повредит производительность, чем справка.

0
ответ дан chakrit 28 November 2019 в 03:10
поделиться

Избегайте финализаторов. Нет никакой гарантии, что их назовут своевременно. Могло потребоваться довольно долгое время, прежде чем Система управления памятью (т.е. сборщик "мусора") решит собрать объект с финализатором.

Многие люди используют финализаторы, чтобы сделать вещи как близкие сокетные соединения или удалить временные файлы. Путем выполнения, таким образом, Вы делаете свое поведение приложения непредсказуемым и связанным с тем, когда JVM идет в GC Ваш объект. Это может привести к "из памяти" сценарии, не из-за "кучи" Java, исчерпываемой, а скорее из-за системы, исчерпывающей дескрипторы для конкретного ресурса.

Еще одна вещь иметь в виду состоит в том, что представление вызовов к System.gc () или такие молотки может показать хорошие результаты в Вашей среде, но они не обязательно переведут в другие системы. Не все выполняют ту же JVM, существуют многие, SUN, IBM J9, BEA JRockit, Гармония, OpenJDK, и т.д. Эта JVM, которой все приспосабливают JCK (те, которые были официально протестированы, который), но имеет большую свободу когда дело доходит до создания вещей быстро. GC является одной из тех областей, в которые все вкладывают капитал в большой степени. Используя молоток часто будет времена уничтожать то усилие.

0
ответ дан Ron 28 November 2019 в 03:10
поделиться
Другие вопросы по тегам:

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