powered by simpleCommunicator - 2.0.56     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / AppDomain.Unload
4 сообщений из 4, страница 1 из 1
AppDomain.Unload
    #38630414
Badabum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
добрый день.
Есть сервис, при вызове создается домен, загружаются из BD необходимые сборки (это было нужно из-за поддержки версий, т.е. в одном случае одна версия в другом другая). Домен сохраняется в некий пул вида
Код: c#
1.
Dictionary<String, AppDomain> listDomain

,
пул инициализируется вот таким образом:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
public void Init(int processQueueInterval = INTERVAL_UNLOAD_DOMAIN)
        {
            //if (string.IsNullOrEmpty(pathToLogFile))
            if (listDomain != null)
                return;

            listDomain = new Dictionary<string, AppDomain>();
            queue = new Queue<String>();

            if (processQueueInterval > 0)
            {
                logQueueThread = new Thread(() =>
                {
                    while (workExists)
                    {
                        Thread.Sleep(processQueueInterval);
                             // Выгрузка домена
                            ProcessQueue();
                    }
                });
                logQueueThread.IsBackground = true;
                logQueueThread.Start();
            }
        }


При необходимости выгрузить домен, его имя бросается в очередь
Код: c#
1.
 Queue<String> queue

, где он должен выгрузиться
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
private void ProcessQueue()
        {
            bool runGC = queue.Count > 0;
            while (queue.Count > 0)
            {
                String nameDomain = queue.Dequeue();
                if (nameDomain != null)
                {
                    RemoveDomain(nameDomain);
                }
            }

            if ((runGC) && (listDomain.Count == 0))
                GC.Collect(2);
        }


Проблема с раходом памяти, т.к. в итоге все падает когда выело всю память. Т.е. код для выгрузки вызывается, но толку от этого ни какого. То-ли GC не успевает отработать, то ли он вообще не выгрузился.....
Есть какая идея - куда копать?
...
Рейтинг: 0 / 0
AppDomain.Unload
    #38630437
Badabum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
да, сам метод выгрузки:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
private void RemoveDomain(String nameDomain)
        {
            if (!listDomain.ContainsKey(nameDomain)) return;
            AppDomain.Unload(listDomain[nameDomain]);
            Guid sId = Guid.Empty;
            Guid.TryParse(nameDomain, out sId);
            Log.WriteLog(sId, "DomainManager.RemoveDomain", "Unloaded domain: " + nameDomain, LogWarning.Trace);
            listDomain.Remove(nameDomain);
            workExists = (listDomain.Count != 0);
        }


Имя домена задается как Guid, посему и парсится им-же.
...
Рейтинг: 0 / 0
AppDomain.Unload
    #38630449
petalvik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Badabum,

копать в сторону профилировщика. Профайлер покажет, где именно растёт память.

Queue<string> - это наверняка System.Collections.Generic? Тогда ахтунг... Непотокобезопасная очередь используется в разных потоках.
Также нутром чую, что workExists не volatile.
Ну и вместо Thread.Sleep лучше применить какой-нибудь примитив синхронизации.
...
Рейтинг: 0 / 0
AppDomain.Unload
    #38630469
Badabum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Мдя.. ищу чем можно смотреть...
По поводу workExists - точно так, поправлю...
А вот чем Queue не подходит - доступ к нему залочен локом:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
public void UnloadDomain(String nameDomain)
        {
            lock (lockObj)
            {
                if (queue == null) return;
                Guid sId = GetSid(nameDomain);
                Log.WriteLog(sId, "DomainManager.UnloadDomain", "Поставлен на удаление domain: " + nameDomain, LogWarning.Trace);
                queue.Enqueue(nameDomain);
            }
        }


А дальше вся работа в методе
Код: c#
1.
ProcessQueue()

. Queue содержит имена доменов, которые нужно выгрузить. Какие могут быть грабли?
...
Рейтинг: 0 / 0
4 сообщений из 4, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / AppDomain.Unload
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]