Забавный баг
Mar. 23rd, 2009 09:57 am![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Третий день ловлю баг, связанный с тем, что TCP сервер под большой нагрузкой падает с ошибкой out of memory, хотя ему выделено всего 800 мег и еще гиг физической памяти свободно. На каждое воспроизведение бага - сутки работы сервера под нагрузкой в несколько раз больше рабочей.
Оказалось - нехватка виртуальной памяти, причем вообще - не самой памяти, а ее адресного пространства. Менеджер памяти при выделении/удалении сильно фрагментирует память, в итоге адресам становится мало 2^31 и все падает, с ошибками типа "not enough storage" в самых левых функциях вроде записи в инишник.
Причем, западло в том, что увидеть это число в Task Manager нельзя, нужно смотреть Process Explorer или делать лог perfmon-ом.
Оказалось - нехватка виртуальной памяти, причем вообще - не самой памяти, а ее адресного пространства. Менеджер памяти при выделении/удалении сильно фрагментирует память, в итоге адресам становится мало 2^31 и все падает, с ошибками типа "not enough storage" в самых левых функциях вроде записи в инишник.
Причем, западло в том, что увидеть это число в Task Manager нельзя, нужно смотреть Process Explorer или делать лог perfmon-ом.
no subject
Date: 2009-03-23 08:06 am (UTC)Вот в том числе из-за таких вещей и возникает желание переходить на .net.
no subject
Date: 2009-03-23 08:12 am (UTC)no subject
Date: 2009-03-23 08:28 am (UTC)Еще можно перейти на какую-нибудь альтернативную кучу типа quickheap - который жрет больше памяти, зато лишен упомянутого недостатка, а по эффективности кроет стандартные реализации, как бык овцу (http://rsdn.ru/article/dotnet/GCnet.xml#EPD)
no subject
Date: 2009-03-23 09:17 am (UTC)no subject
Date: 2009-03-25 10:11 am (UTC)no subject
Date: 2009-03-23 08:44 am (UTC)no subject
Date: 2009-03-23 09:09 am (UTC)no subject
Date: 2009-03-23 10:02 am (UTC)no subject
Date: 2009-03-23 11:01 am (UTC)no subject
Date: 2009-03-23 08:34 pm (UTC)no subject
Date: 2009-03-25 10:12 am (UTC)no subject
Date: 2009-03-25 10:34 am (UTC)no subject
Date: 2009-03-23 09:00 am (UTC)no subject
Date: 2009-03-23 09:10 am (UTC)no subject
Date: 2009-03-23 09:12 am (UTC)no subject
Date: 2009-03-23 09:23 am (UTC)no subject
Date: 2009-03-23 09:48 am (UTC)no subject
Date: 2009-03-23 09:45 am (UTC)Фрагментация памяти создает много частично заполненых страниц и свопинг начнется раньше. А если учесть и то, что размер указателя вырос, то программа может потребовать значительно больше памяти.
no subject
Date: 2009-03-23 09:52 am (UTC)Значительно памяти больше программа не потребует. Даже если предпложить что вся программа состоит только из указателей, то памяти будет тратить всего в 2 раза больше, что совсем не много.
no subject
Date: 2009-03-23 10:23 am (UTC)А цену рабочего дня программиста надо сравнивать с ценой памяти, помноженной на количество пользователей...
no subject
Date: 2009-03-23 10:45 am (UTC)no subject
Date: 2009-03-23 10:56 am (UTC)no subject
Date: 2009-03-23 09:10 am (UTC)no subject
Date: 2009-03-23 09:46 am (UTC)Похоже, она типична для телекома...
no subject
Date: 2009-03-23 10:11 am (UTC)no subject
Date: 2009-03-23 11:02 am (UTC)no subject
Date: 2009-03-26 06:01 pm (UTC)no subject
Date: 2009-03-26 06:05 pm (UTC)no subject
Date: 2009-03-23 09:45 am (UTC)no subject
Date: 2009-03-23 09:54 am (UTC)Это реалтаймовый сервер сбора данных, там вся идея именно в том, чтобы держать в памяти множество мелких объектов, чтобы не грузить их из СУБД каждый раз. Но вообще там есть недоработка в этом кэше (лишние объекты лежат в памяти слишком долго), которую можно исправить, но это усложнит код и потребует в очередной раз прогонять все тестирование вдоль и поперек
no subject
Date: 2009-03-25 10:12 am (UTC)no subject
Date: 2009-03-25 10:34 am (UTC)no subject
Date: 2009-03-23 12:36 pm (UTC)интересно, можно ли его, или подобный, раньше чем за сутки обнаруживать - вроде можно, нет?
no subject
Date: 2009-03-23 01:18 pm (UTC)no subject
Date: 2009-03-23 01:10 pm (UTC)Всё хорошо работало до тех пор, пока люди не написали алгоритм, который в своей работе использует числа порядка двойки в степени 5033164800 (600*1024*1024*8). На такие числа этот наколенный класс пытается выделить непрерывный кусок памяти объёмом в 600 мегабайт, что ему, естественным образом, удаётся не всегда. Язык - C++. К счастью, проблема стала очевидной, когда в отладчике увидели падение на строке new unsigned int[digitsCount] и посмотрели, чему равен digitsCount.
no subject
Date: 2009-03-23 09:23 pm (UTC)no subject
Date: 2009-03-23 09:32 pm (UTC)Наверное. ;)