сомнения относительно управления памятью в .NET

На всякий случай Вы, возможно, должны были бы, это может помочь, если Вам нужно к захват unicode аргументы на Win32 (2K, XP и т.д.):


from ctypes import *

def wmain(argc, argv):
    print argc
    for i in argv:
        print i
    return 0

def startup():
    size = c_int()
    ptr = windll.shell32.CommandLineToArgvW(windll.kernel32.GetCommandLineW(), byref(size))
    ref = c_wchar_p * size.value
    raw = ref.from_address(ptr)
    args = [arg for arg in raw]
    windll.kernel32.LocalFree(ptr)
    exit(wmain(len(args), args))
startup()
5
задан claws 10 February 2011 в 04:55
поделиться

6 ответов

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

Но память - не единственный ресурс, который ограничен. Возьмите файлы. Обычно только одно приложение может одновременно открыть файл, так как это может стать беспорядочным, если несколько человек попытаются записать в один и тот же файл. Базы данных имеют ограниченное количество подключений. И так далее. Сборщик мусора не отслеживает ни один из этих ресурсов. И он не знает, насколько срочно их закрыть.

Конечно, вы можете открыть FileStream и читать из него, не закрывая его впоследствии. если вы обнуляете ссылку на объект, в конечном итоге сборщик мусора, вероятно, решит собрать объект FileStream, который запустит свой Finalizer, и файл будет правильно закрыт. Но это может занять много времени, а пока файл заблокирован.

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

Поэтому правильная утилизация объекта Disposable является хорошей практикой. Иногда можно было уйти, не сделав этого, но это плохой стиль. Если объект реализует IDisposable, это потому, что он хочет, чтобы вы очистили его, когда закончите его использовать.

6
ответ дан 18 December 2019 в 06:23
поделиться

Некоторые классы в .NET framework являются просто оболочками Windows API или сторонних сборок. Эти API-интерфейсы не являются управляемым кодом (они могут быть написаны на C ++ или представляют собой старые сборки COM), и сборщик мусора не знает, когда они больше не требуются приложению.

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

Метод Dispose, реализованный в Framework для этих классов, вызывает внутренний метод Close, необходимый для завершения экземпляра чистым способом. Таким образом, все классы, которые обертывают неуправляемый код, должны реализовывать интерфейс Disposable, чтобы обеспечить реализацию метода закрытия.

Затем, когда вы создаете экземпляр этого класса, рекомендуется делать это с помощью оператора using, потому что тогда, когда вы покидаете область видимости, метод Dispose вызывается автоматически.

11
ответ дан 18 December 2019 в 06:23
поделиться
1
ответ дан 18 December 2019 в 06:23
поделиться

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

То же самое и с файловыми потоками. Есть еще что-то в буфере? Должно ли это быть записано в файл перед закрытием дескриптора файла? GC не знает об этом - код доступа знает.

2.) Это то, что следует из этого. Итак, если у вас есть открытые файловые потоки и внутренний буфер - в методе dispose вы должны очистить буфер, записать его в файл и закрыть файл hanlde.

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

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

3
ответ дан 18 December 2019 в 06:23
поделиться

Это хороший вопрос, и многие разработчики, кажется, не понимают его.

На высоком уровне управляемые ресурсы - это ресурсы, которые выделяются и отслеживаются .Net. Память, используемая ресурсом, поступает из пула, выделенного для .Net, и среда выполнения .Net отслеживает все ссылки между управляемыми ресурсами. Это отслеживание (я уверен, что это неправильный термин, но здесь его будет достаточно) позволяет среде выполнения .Net узнать, когда данный ресурс больше не используется и, следовательно, может быть освобожден. Таким образом, неуправляемые ресурсы - это ресурсы, выделенные вне этого управляемого пула .Net и не отслеживаемые средой выполнения. Чаще всего это ссылки на ОС или ресурсы внешних приложений. Существует множество сложных причин, по которым среда выполнения .Net не может «видеть» неуправляемый ресурс. но мне нравится думать об этом так: .Net - это обнесенный стеной сад разработки, в который вы должны войти, чтобы использовать. Вы можете проделать дыру в стене, чтобы видеть снаружи (например, PInvoke), но вы не можете владеть ресурсом на другой стороне.

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

Надеюсь, это поможет.

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

Надеюсь, это поможет.

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

Надеюсь, это поможет.

2
ответ дан 18 December 2019 в 06:23
поделиться

Неуправляемые ресурсы - это дескрипторы ресурсов, принадлежащих и контролируемых операционной системой (кроме памяти, конечно).

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

Чтобы освободить эти неуправляемые ресурсы обратно в операционную систему, вам нужно явно освободить их, удалив их. Отсюда и использование IDisposable и ключевого слова using.

1
ответ дан 18 December 2019 в 06:23
поделиться
Другие вопросы по тегам:

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