Страница: 1 | 2 | 3 |
|
Вопрос: GC финализирует объект без причины
|
Добавлено: 01.09.12 20:36
|
|
Номер ответа: 35 Автор ответа: Programmer
Вопросов: 71 Ответов: 246
|
Профиль | | #35
|
Добавлено: 03.09.12 00:40
|
- Если есть какие-то цели, котоыре преследуются кодом, нужно было о них написать, я описал недостатки, присутствующие в коде, а не занимался декомпозицией механизмов работы.
Спасибо, но код прекрасно справляется со своими целями, а вопрос был совсем о другом. В один прекрасный момент при вызове Write поле _disposedAt содержит "at ~SimpleDataBuffer", при этом предыдущий вызов Write (на позицию ниже по стэку) был выполнен успешно.
Асинхронное исключение может произойти в любом месте программы в любой момент времени, в том числе там где я указал. Если кто-то вздумает вызвать Thread.Abort, так тому и быть. Остальные возможные асинхронные исключения неминуемо приведут к немедленному завершению процесса, поэтому не рассматриваются.
Ответить
|
Номер ответа: 38 Автор ответа: Artyom
Разработчик
Вопросов: 130 Ответов: 6602
|
Профиль | | #38
|
Добавлено: 03.09.12 01:30
|
Programmer пишет:
Спасибо, но код прекрасно справляется со своими целями, а вопрос был совсем о другом. В один прекрасный момент при вызове Write поле _disposedAt содержит "at ~SimpleDataBuffer", при этом предыдущий вызов Write (на позицию ниже по стэку) был выполнен успешно.
1) Смотри используются ли где-нибудь в программе WeakReference. Это еще один способ когда можно получить доступ к финализированному объекту, правда в очень маленьком окне.
2) Используется ли доступ к другим объектам (в т.ч. на запись, даже неявно). Учитывая что ты нашлепал финализаторов от души, эта ситуация вполне возможна.
3) Сделай разные флаги для фиксации вызовов финализатора и Dispose, чтоб можно было отдельно отследить ситуацию когда каким-то образом была получена ссылка на "финализированный объект" и ссылка на объект, которому был сделан ручной Dispose
Это если говорить в частности.
Если вобщем, то то что я писал выше, выпилить все что касается управления памяти.
Ответить
|
Номер ответа: 40 Автор ответа: Programmer
Вопросов: 71 Ответов: 246
|
Профиль | | #40
|
Добавлено: 03.09.12 22:09
|
Ты забыл, что у меня еще BinaryReader и BinaryWriter.
Пожалуйста:
Без пула - 8237.
С пулом - 1528.
-
- var array = new byte[] { 1, 2, 3, 4, 5 };
- int count = 10000000;
- Stopwatch sw = StopwatchInt.StartNew();
- for (int i = 0; i <= count; i++)
- {
- var ms = new MemoryStream();
- var wr1 = new BinaryWriter(ms);
- var rr = new BinaryReader(ms);
- wr1.Write(array, 0, 5);
- wr1.Close();
- rr.Close();
- ms.Dispose();
- }
- Console.WriteLine(sw.ElapsedMilliseconds);
-
- sw = Stopwatch.StartNew();
- var pool = new System.Tuple<MemoryStream, BinaryWriter, BinaryReader>[count + 2];
- var cachedMs = new MemoryStream();
- pool[0] = Tuple.Create(cachedMs, new BinaryWriter(cachedMs), new BinaryReader(cachedMs));
- for (int i = 0; i <= count; i++)
- {
- MemoryStream ms;
- BinaryReader rr;
- BinaryWriter wr1;
- lock (pool)
- {
- var el = pool;
- ms = el.Item1;
- wr1 = el.Item2;
- rr = el.Item3;
-
- pool = null;
- }
- ms.Position = 0;
- ms.SetLength(0);
- wr1.Write(array, 0, 5);
- lock (pool)
- {
- pool[i + 1] = System.Tuple.Create(ms, wr1, rr);
- }
- }
- Console.WriteLine(sw.ElapsedMilliseconds);
- Console.ReadLine();
Смотри используются ли где-нибудь в программе WeakReference. Это еще один способ когда можно получить доступ к финализированному объекту, правда в очень маленьком окне. Такого нет.
Используется ли доступ к другим объектам (в т.ч. на запись, даже неявно). Учитывая что ты нашлепал финализаторов от души, эта ситуация вполне возможна. Как видишь, в этом фиинализаторе не используются другие объекты.
Вообще я посмотрел рефлектором MemoryStream и BinaryReader-BinaryWriter и обнаружил, что они ничего не делают в Dispose (в основном только устанавливают флаг disposed), так что без финализатора можно обойтись.
Сделай разные флаги для фиксации вызовов финализатора и Dispose, чтоб можно было отдельно отследить ситуацию когда каким-то образом была получена ссылка на "финализированный объект" и ссылка на объект, которому был сделан ручной Dispose Раз воспроизвести не получится, придется поверить мне на слово. И вот что я скажу. Когда я только обнаружил ошибку, я добавил установку флага в Dispose, но не в финализатор. Так вот, когда ошибка повторилась, флаг был пустым. Только когда я добавил установку флага в финализатор, флаг оказался установленным при повторении ошибки.
Если снова словлю ошибку - выложу каким образом получена ссылка на объект.
Кстати, можешь рассказать подробнее про твой игровой сервер? Меня интересует, время отклика сервера и частота передачи пакетов для каждого клиента (из 65 000). На каком железе тестировал? Сколько расход ЦП?
Ответить
|
Страница: 1 | 2 | 3 |
Поиск по форуму