Здравствуйте, S., Вы писали:
S.>Сборшщик мусора не удаляет объект, я точно знаю что объект
S.>этот мне больше не нужен. Есть ли какой-нибудь способ узнать, кто
S.>ссылается на не нужный мне объект?
Поищи профайлер, который умеет делать снапшоты памяти.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Здравствуйте, S., Вы писали:
S.>Есть ли какой-нибудь способ узнать, кто
S.>ссылается на не нужный мне объект?
.NET Memory ProfilerЕсли больной очень хочет жить, врачи бессильны. ©Ф.Раневская
Здравствуйте, <Аноним>, Вы писали:
А>при необходимости можно вызвать принудительную сборку мусора, вплоть до очистки всех неиспользуемых объектов
Не стоит, это очень нехорошо.

Для этого нужно использовать слабые ссылки WeakReference.
Здравствуйте, rsn81, Вы писали:
R>Здравствуйте, <Аноним>, Вы писали:
А>>при необходимости можно вызвать принудительную сборку мусора, вплоть до очистки всех неиспользуемых объектов
R>Не стоит, это очень нехорошо.
R>Для этого нужно использовать слабые ссылки WeakReference.
Чистку мусора я конечно же вызываю и конечно же это ничего не меняет. и WeakReference
я использую ... иначе как понять что объект еще не удален.
Я тут заметил что сборщик мусора ведет себя по разному
в зависимости от того как я запускаю приложение.
т.е. Из студии в режими отладки одно поведение, просто с диска скомпилированный
проект другое ... а скомпилированный в режиме релиза третье.
Кто-нибудь может пояснить чем отличаются различные режимы запуска для сборщика мусора?
И еще есть у меня вот такой пример: (Извеняюсь что много кода)
using System;
using System.Collections.Generic;
using System.Text;
namespace User
{
public class Test
{
}
public class Stat
{
public static Test CreateTest(Test Parent, Type ObjectType)
{
return Activator.CreateInstance(ObjectType) as Test;
}
}
class Program
{
static void Main(string[] args)
{
List<Type> lT = new List<Type>();
lT.Add(typeof(Object));
lT.Add(typeof(Object));
lT.Add(typeof(Object));
lT.Add(typeof(Object));
lT.Add(typeof(Object));
lT.Add(typeof(Object));
lT.Add(typeof(Object));
lT.Add(typeof(Object));
lT.Add(typeof(Object));
lT.Add(typeof(Object));
lT.Add(typeof(Object));
lT.Add(typeof(Object));
lT.Add(typeof(Object));
lT.Add(typeof(Object));
lT.Add(typeof(Object));
lT.Add(typeof(Object));
lT.Add(typeof(Object));
lT.Add(typeof(Object));
lT.Add(typeof(Object));
lT.Add(typeof(Object));
lT.Add(typeof(Object));
lT.Add(typeof(Object));
lT.Add(typeof(Object));
lT.Add(typeof(Object));
lT.Add(typeof(Object));
lT.Add(typeof(Object));
lT.Add(typeof(Object));
// Все работает правильно
//Test tt = new Test();
// Работает не правильно
Test tt = Activator.CreateInstance(typeof(Test)) as Test;
WeakReference wr = new WeakReference(tt);
tt = null;
long pGC1 = GC.GetTotalMemory(false);
GC.Collect();
GC.WaitForPendingFinalizers();
int iiII = -1;
if (wr.Target != null)
{
Console.WriteLine("Error");
iiII = GC.GetGeneration(wr);
}
else
{
Console.WriteLine("OK");
}
Test n1 = Stat.CreateTest(null, typeof(Test));
Test n2 = Stat.CreateTest(null, typeof(Test));
Console.ReadLine();
}
}
}
Так вот если я объект создаю через активатор, то работает не правильно, если напрямую через new то правильно.
Такая ситуация наблюдается только при запуске из студии
У меня есть более сложный пример в котором подобная же ситуация наблюдается всегда кроме запуска из релизной сборки.
В общем я не знаю как понимать то, что происходит.
Если кто может прояснить ситуацию, объясните пожалуйста в чем дело.
Спасибо!
Здравствуйте, S., Вы писали:
S.>Я тут заметил что сборщик мусора ведет себя по разному
S.>в зависимости от того как я запускаю приложение.
так оно и есть:
Когда JIT-компилятор компилирует IL-код метода в машинный код, он проверяет, была ли сборка, в которой определен метод, скомпилирована без оптимизаций и выполняется ли процесс с отладчиком. Если и то и другое верно, JIT-компилятор генерирует внутреннюю таблицу корней метода так, чтобы искусственно продлить время жизни всех переменных до завершения метода.
...
При компиляции метода JIT-компилятор смотрит, чтобы сборка, определяющая метод, содержала атрибут SystemJDiagnosticsDebuggableAttribute, а аргумент isJITOptimizerDisabled его конструктора был равен true. Если JIT-компилятор обнаружит, что этот атрибут задан, он также скомпилирует метод, искусственно продлевая время жизни всех переменных до окончания метода. При указании параметра компилятора /debug+ компилятор С# добавляет этот атрибут в готовую сборку. Учтите, что параметр /optimize+ компилятора С# может вновь включить оптимизацию, поэтому при выполнении такого эксперимента этот параметр компилятора указывать не следует. Таким образом, JIT-компилятор помогает своевременно выполнить отладку.
(c)Jeffrey Richter CLR via C# стр.455
з.ы. может кроме продления жизни переменных он и еще чего делает в debug-е
... << RSDN@Home 1.2.0 alpha rev. 688>>
Здравствуйте, <Аноним>, Вы писали:
А>Здравствуйте, S., Вы писали:
S.>>Добрый день
S.>>Сборшщик мусора не удаляет объект, я точно знаю что объект
S.>>этот мне больше не нужен. Есть ли какой-нибудь способ узнать, кто
S.>>ссылается на не нужный мне объект?
S.>>Анализ кода показывает, что на объект больше ссылок быть не должно.
S.>>Спасибо!
А>если GC не уничтожает объект, то это не обязательно значит что на объект есть ссылка
А>возможно просто время не пришло для этого объекта
Вроде GC очищает память только тогда, когда ее перестает хватать...
А>при необходимости можно вызвать принудительную сборку мусора, вплоть до очистки всех неиспользуемых объектов... << RSDN@Home 1.1.4 stable SR1 rev. 568>>