Чем отличается управление памятью в Java и C #? - PullRequest
4 голосов
/ 17 марта 2010

Я читал 2010 CWE / SANS 25 самых опасных ошибок программирования , и одна из записей предназначена для Буферное копирование без проверки размера ввода . Он предлагает использовать язык с функциями для предотвращения или смягчения этой проблемы и говорит:

Например, многие языки, которые выполнять собственное управление памятью, такие как Java и Perl, не подлежат для буфера переполнения. Другие языки, такие как Ada и C #, обычно обеспечивают защита от переполнения, но защита может быть отключена программист.

Я не знал, что Java и C # различались каким-либо значимым образом в отношении управления памятью. Как получается, что Java не подвержена переполнению буфера, а C # защищает только от переполнения? И как можно отключить эту защиту в C #?

Ответы [ 2 ]

5 голосов
/ 17 марта 2010

Java не поддерживает необработанные указатели (строго говоря, не поддерживает арифметику указателей).

В C # вы можете использовать небезопасный код и указатели , а также неуправляемую память, что делает возможным переполнение буфера. См. Ключевое слово unsafe .

Для обеспечения безопасности типов, C # не поддерживает указатель арифметика, по умолчанию. Тем не менее, по используя ключевое слово unsafe, вы можете определить небезопасный контекст, в котором указатели могут быть использованы. Для большего информацию об указателях смотрите в тема Типы указателей .

4 голосов
/ 20 марта 2012

Хорошие ответы. Я хотел бы добавить, что Java зависит от использования стека или расположения кучи памяти. C # делает то же самое. Идея использования необработанных указателей является дополнением к C #, которое происходит из его фона кода C. Хотя C # и C / C ++ не являются одним и тем же языком кода, они имеют общую семантику общности. Идея использования «небезопасного» кода позволяет избежать хранения больших объектов в куче, где память ограничена примерно 2 ГБ на экземпляр времени выполнения (для C # на CLR, для Java на экземпляр JVM) без существенного снижения производительности из-за сбора мусора. В некоторых случаях вы можете использовать способность C # использовать небезопасные или управляемые вручную указатели памяти, чтобы обойти тот факт, что существует не так много сторонних инструментов для решения проблем, таких как кэширование вне кучи.

Я бы предупредил, что если вы используете небезопасный код, обязательно ознакомьтесь с «Одноразовыми типами» и «Финализаторами». Это может быть довольно продвинутой практикой, и последствия неправильной утилизации ваших предметов такие же, как с кодом C ... страшная УТЕЧКА ПАМЯТИ. В результате у вас заканчивается память для вашего приложения, и оно падает (не очень хорошо). Вот почему C # не разрешает это по умолчанию, и вам необходимо переопределить любое использование указателей, управляемых вручную, с помощью ключевого слова «unsafe». Это гарантирует, что любая память, обработанная вручную, является преднамеренной. При работе с ключевым словом «unsafe» наденьте шапку C-кода.

Отличная ссылка на это была в главе Эндрю Троелсена «Понимание времени жизни объекта» в «Pro C # 2010 и .Net Platform». Если вы предпочитаете ссылки в Интернете, см. Веб-сайт MSDN Завершение выполнения и утилизация для очистки неуправляемых ресурсов

Последнее замечание: неуправляемая память высвобождается в части финализатора вашего объекта (~ ObjectName () {...}). Эти шаблоны увеличивают производительность, поэтому, если вы работаете со сценариями с меньшей задержкой, вам лучше всего обслуживать объекты светом. Если вы имеете дело с человеческим ответом, тогда вы должны рассмотреть это там, где это абсолютно необходимо.

...