Почему каждая среда выполнения ООП не позволяет вручную (сборку мусора) экземпляров объектов? - PullRequest
1 голос
/ 18 сентября 2010

Вы можете создавать новые объекты, но когда вы закончите использовать их, у вас не будет и реального способа их немедленно уничтожить?

Почему не каждая среда выполнения ООП реализует такое поведение?

Я уверен, что мы, как разработчики, могли (часто) организовывать уничтожение экземпляров объектов после их использования.

function work(){
    var p1:Point = new Point(x, y);
    var p2:Point = new Point(x2, y2);

    ....

    destroy p1;
    destroy p2;
}

Ответы [ 7 ]

9 голосов
/ 18 сентября 2010

Говоря из .NET, ответ - безопасность памяти.

Рассмотрим два элемента A и B (объекты или методы), оба из которых содержат ссылку на Объект X.
И теперь A выполняет destroy X;,B остается с недействительной ссылкой.Это распространенная ошибка в неуправляемых языках.Удаление ручного уничтожения предотвращает это.

Но не менее важный вопрос: много ли это поможет?Ответ - нет.Кратковременная память очень дешева в .NET.Разрушение, как вы предлагаете, не будет иметь никакой ценности.

5 голосов
/ 18 сентября 2010

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

Сценарий, который вы показываете выше, является распространенным, но далеко не единственным.Что если вы вернете ссылку на один из объектов?Что если вы передадите ссылку на вызываемый метод (где он может храниться)?И т. Д. И т. Д. Это все вопросы, о которых нужно подумать, прежде чем вы сможете ответственно уничтожить свои объекты.В целом они известны как «владение».

Другая сторона медали в том, действительно ли она будет иметь положительный эффект, если будет иметь возможность уничтожать объекты в указанной точке во время выполнения?Это делает возможными деструкторы и RAII в C ++, что является очень мощной идиомой.У Java его нет, и когда я начинал использовать Java, я часто скучал по нему.Однако в Java также есть способы эффективного решения этих проблем (например, блок finally).Как бы ни был элегантен RAII, он по-прежнему не оплачивает весь беспорядок, который может вызвать ручное управление памятью.

Тогда вы можете предположить: «Почему у нас не может быть и того и другого: явное уничтожение объектов, когда я хочуа сборка мусора для отдыха? ».И вы можете начать бегать за прикрытием до того, как авторы компилятора и разработчики JVM получат вас :-) Это сильно усложнит ситуацию, никто не сделает это без действительно огромного, ощутимого преимущества.И ручное управление памятью не предлагает такой вещи.

2 голосов
/ 18 сентября 2010

Причина того, что не все языки OO имеют сборку мусора (Java) или явное освобождение памяти (C ++), является следствием стратегии, выбранной при разработке каждого языка. Java не позволяет программистам явно распределять и освобождать память. Вместо этого программисты обрабатывают ссылочные переменные , когда они делают

Point p = new Point(x,y);//p is a reference variable

и освобождение p выполняется посредством сборки мусора ( автоматически ). Чтобы иметь сборку мусора, вы выбираете явную символьную ссылку и не используете указатели. В результате C ++ не имеет сборки мусора и не может быть предоставлен как присущая языку . Программисты должны явно освободить память, используя

delete p;

Или напишите свои собственные реализации сборки мусора. Так что либо у вас есть сборка мусора или ручное освобождение в зависимости от дизайна языка ОО. Вы не можете иметь оба.

2 голосов
/ 18 сентября 2010

Нет, просто нет.Одна из лучших вещей, которые Java / C # дает вам по сравнению с C ++, - это управление памятью - если вам нужно позаботиться об этом самостоятельно, это более подвержено ошибкам, и если у людей есть возможность, они будут использовать и злоупотреблять ими, создавая все больше ошибок и утечек памятиили забыв освободить что-то или сделав это слишком рано.Разработка / кодирование больших проектов достаточно сложна, не задумываясь об управлении памятью.

1 голос
/ 19 сентября 2010

Вы можете установить существующую ссылку на null или аналогичную в большинстве языков, что позволит среде выполнения собирать мусор, если она пожелает.

Я полагаю, что цена, которую вы платите за удобство работы системы с вашей памятью, заключается в том, что вы теряете большую часть способности делать это самостоятельно, когда вы хотите

1 голос
/ 18 сентября 2010

Для Java см. Runtime.gc () .

Для C # см. System.GC.Collect

Я не совсем уверен в C #, но в Java вы можете только запросить о том, что происходит сборка мусора, но решение о том, нужно ли на самом деле удалять неиспользуемые ссылки, остается за виртуальной машиной.

Существует много споров о том, работает ли лучше управление памятью в стиле C ++ по сравнению со сборкой мусора в интерпретируемых языках, но если вы работаете с Java или C #, я бы сомневался в том, действительно ли вам нужно принудительно собирать мусор и в общем, если вы переходите с C ++, я бы рекомендовал не поддаваться искушению управлять памятью и позволить оптимизации виртуальной машины сделать это за вас. Вы должны просто убедиться, что вы освободили все ссылки на объекты, которые вы не используете, чтобы они могли быть сборщиком мусора. Я бы не беспокоился о , когда .

1 голос
/ 18 сентября 2010

C ++ - язык ООП; и он предоставляет ключевое слово «new», которое можно использовать для создания объекта, и ключевое слово «delete», которое можно использовать для уничтожения объекта. Удалить объект может иметь катастрофические последствия в C ++, если не использовать с осторожностью; если один объект имеет два указателя, ссылающихся на него, и вы удаляете объект из одного из указателей, другой указатель становится недействительным, и любая попытка его использования будет неопределенным поведением (обычно программа пытается использовать значение в ячейке памяти ; который уже может быть перераспределен для других целей во время выполнения)

...