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

StackOverflow https://stackoverflow.com/questions/1868604

Вопрос

Допустим, вы хотите написать высокопроизводительный метод, который обрабатывает большой набор данных. Почему разработчики не должны иметь возможность включать ручное управление памятью вместо того, чтобы быть вынужденными перейти на C или C ++?

void Process()
{
    unmanaged
    {
        Byte[] buffer;
        while (true)
        {
            buffer = new Byte[1024000000];

            // process

            delete buffer;
        } 
    }   
}
Это было полезно?

Решение

Потому что позволяя вам вручную удалить блок памяти, в то время как на него все еще могут быть ссылки (и во время выполнения не может знать, что без цикла GC) может создавать висящие указатели и, таким образом, разорвать Безопасность памяти. Анкет Языки GC, как правило, безопасны для памяти по дизайну.

Тем не менее, в C#, в частности, вы уже можете делать то, что хотите:

void Process()
{
    unsafe
    {
        byte* buffer;
        while (true)
        {
            buffer = Marshal.AllocHGlobal(1024000000);

            // process

            Marshal.FreeHGlobal(buffer);
        } 
    }   
}

Обратите внимание, что, как и в C/C ++, у вас есть полная арифметика указателя для необработанных типов указателей в C# - Итак, buffer[i] или же buffer+i являются действительными выражениями.

Другие советы

Если вам нужна высокая производительность и подробный контроль, возможно, вам следует написать то, что вы делаете в C или C ++. Не все языки полезны для всего.

Отредактирован для добавления: один язык не будет хорошим для всего. Если вы добавите все полезные функции на всех хороших языках программирования, вы получите действительно большой беспорядок, намного хуже, чем C ++, даже если вы можете избежать несоответствия.

Особенности не бесплатны. Если у языка есть функция, люди, вероятно, будут его использовать. Вы не сможете выучить C# достаточно хорошо, не изучая новые процедуры управления памятью C#. Команды компилятора будут реализовать его за счет полезных функций компилятора. На этом языке, вероятно, будет трудно проанализировать как C или C ++, и это приводит к медленному сборнику. (Как парень C ++, я всегда удивляюсь, когда компилирую один из наших проектов C#. Компиляция кажется почти мгновенной.)

Особенности конфликта друг с другом, иногда неожиданным образом. C90 не может сделать так же хорошо, как Фортран на расчетах матрицы, поскольку возможность, как указаны C -псевдоним, предотвращает некоторые оптимизации. Если вы разрешаете арифметику указателя на языке, вы должны принять его последствия.

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

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

В примере, который вы опубликовали, почему бы просто не стереть буфер и повторно использовать его?

Коллекционер мусора .NET очень хорош в разработке, какие объекты больше не ссылаются, и своевременно освобождает соответствующую память. Фактически, сборщик мусора имеет особую кучу (большую кучу объекта), в которой он ставит такие большие объекты, что оптимизируется для их борьбы.

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

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

Та же причина, по которой большинство ядер не позволят вам планировать собственные потоки. Потому что 99,99+% времени вам на самом деле не нужно, и разоблачение этой функциональности в остальное время только соблазняет сделать что -то потенциально глупое/опасное.

Если вам действительно нужен контроль за памятью мелкого зерна, напишите этот раздел кода в чем -то еще.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top