Неуправляемые ресурсы и GC C#

Рейтинг: 1Ответов: 1Опубликовано: 03.07.2023

Как работает сборщик мусора с объектами, которые используют неуправляемые ресурсы?

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

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

Ответы

▲ 3

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

Однако, если у класса описан метод финализации, сборщик мусора вызывает его перед тем, как освободить объект.

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

Паттерн disposable помогает освобождать ресурсы вручную — через вызов Dispose() или оператор using. Если программист по каким-то причинам не освободил ресурс (забыл или плохо спроектировал кусок приложения), это сделает финализатор. Сложность в том, что паттерн надо реализовать аккуратно, потому что там много тонкостей. Внимательно читайте статью и делайте всё так, как там написано.

Если же вы пишете класс, который содержит другие disposable-классы, просто вызовите в реализации своего метода Dispose() их методы Dispose().

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

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

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