Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Сборка мусора, COM объекты, OutOfMemory

29K
27 октября 2009 года
B@HTy3
17 / / 04.11.2007
Делаю обертку на COM объект.
Код:
class _1CObject : IDisposable
    {
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
            }
            if (Obj != null && Obj.GetType().IsCOMObject)
            {
                System.Runtime.InteropServices.Marshal.ReleaseComObject(Obj);
            }
            Obj = null;
        }

        ~_1CObject()
        {
            Dispose(false);
        }

        static public object _v81Connector;

        /// <summary>
        /// COM объект
        /// </summary>
        public object Obj;


Методы COM объекта возвращают либо ссылку на другой COM объект, либо ValueType (строки или числа). Не зависимо от типа, результат я сохраняю в поле своего класса (Obj). При Dispose я проверяю естественно COM объект это или нет (делать или нет Release). COM объекты которые у нас создаются в результате вызовов, могут быть достаточно большими, как-раз в эти моменты я получаю OutOfMemory.

Вопросы:
1)Должен ли я как-то очищать поле Obj если там хранится ValueType(Int32, Boolean...) и как если должен? Я ведь помечаю, чтобы GC не трогал мой объект GC.SuppressFinalize(this); (возможна утечка через эти типы).
2)Может ли выскакивать это исключение, если утечки памяти нету? Не может например найти память под большой COM объект. GC в этом случае делает дефрагментацию и сборку, если ему не хватает места под COM?

Примечание: если не делать частых вызовов, то утечки не заметно (несколько дней работает нормально). Если вызовы очень частые и COM объекты большие создаем, то спасает вставка
 
Код:
if (Obj != null && Obj.GetType().IsCOMObject)
            {
                System.Runtime.InteropServices.Marshal.ReleaseComObject(Obj);
            }
            Obj = null;
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
29K
01 ноября 2009 года
B@HTy3
17 / / 04.11.2007
Неужели никто с этим не сталкивался некогда? Не могу понять...вот похоже ответ:

http://msdn.microsoft.com/ru-ru/library/9w766t6y.aspx

Это исключение может быть сгенерировано с дополнительным сообщением: Недостаточно свободной памяти для завершения этой операции, которое появляется при вызове метода для объекта COM, возвращающем определяемый пользователем тип, содержащий безопасный массив (массив не фиксированного размера). Это происходит, потому что .NET Framework. не может маршалировать поля структуры с безопасным типом массива.

Как решение, сейчас использую чистку GC при вызове этого исключения
5
01 ноября 2009 года
hardcase
4.5K / / 09.08.2005
Вы у экземпляров своего класса _1CObject метод Dispose вообще вызываете?

Нечего на GC пенять. COM объекты создаются в вообще в другой куче - неуправляемой.
29K
02 ноября 2009 года
B@HTy3
17 / / 04.11.2007
System.Runtime.InteropServices.Marshal.ReleaseComObject(Obj);

Это ведь и есть очистка COM объекта. Dispose вызываю. На случай если где-то забыл, я ведь Finalizator определил. Проблем нету, если GC.Collection делать и если запускаю на машинах больше 1 гб. Вываливается ошибка только когда COM объект пытается вернуть большие(!) "массивы".
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог