closesocket не освобождает память
s = accept(...)
closesocket(s)
После выполнения первой строчки программе выделяется дополнительно 464 байта памяти.
После closesocket эта память системе не возвращается. Почему ???
(Всё проверял очень тщательно)
Ответ очень нужен, потому как пишу http-сервер для долговременной работы. Для него эта проблема очень критична.
программа содержит код:
s = accept(...)
closesocket(s)
После выполнения первой строчки программе выделяется дополнительно 464 байта памяти.
После closesocket эта память системе не возвращается. Почему ???
(Всё проверял очень тщательно)
Ответ очень нужен, потому как пишу http-сервер для долговременной работы. Для него эта проблема очень критична.
Всё ёще интереснее. После closesocket осталась возможность успешной отправки пакета!!!
Всё ёще интереснее. После closesocket осталась возможность успешной отправки пакета!!!
Я посмотрел внимательно примеры и увидел, что тот сокет, который вернула функция accept закрывать не надо. Так что ж мне после каждого accept закрывать слушающий сокет для освобождения памятит, а потом снова его создавть?
Я посмотрел внимательно примеры и увидел, что тот сокет, который вернула функция accept закрывать не надо. Так что ж мне после каждого accept закрывать слушающий сокет для освобождения памятит, а потом снова его создавть?
При таком подходе теряется каждый раз по 728 байт.
При таком подходе теряется каждый раз по 728 байт.
И ещё такая проблема:
если http-сервер запущен длительное время, то даже если на него запросы не поступали, то если сделать запрос ему более, чем после дня работы, то он не сможет его принять с ошибкой WSAENOBUFS.
Интересно, куда это подевались ресурсы сетевой карты, если он просто был в состоянии блокировки после вызова accept. Он целый день ничего не делал, просто ждал и память, занятая им НИСКОЛЕЧКИ НЕ МЕНЯЛАСЬ (ну конечно в своп он выгрузился, я имею в виду всю занятую им виртуальную память).
Код покаж.
Странно все у тебя. Как ты определяеш выделение 464 байтов?closesocket не закрывает? У меня закрывает. И на клиент 0 байтов идет.
Код покаж.
Пуск/Администрирование/Производительность
Создаю столбец слежения за моим процессом.
Там выбираю "рабочее множество".
Ну и смотрю. Это аналогично Mem Usage в Диспетчере задач, за исключением того, что он показвыает в Кб.
Странно все у тебя. Как ты определяеш выделение 464 байтов?closesocket не закрывает? У меня закрывает. И на клиент 0 байтов идет.
Код покаж.
А про отправку клиенту я ничего не говорил. Клиент ничё не присылает и я ему ничё пока что не отправляю. Это потом, если с этим разберусь.
Всё ёще интереснее. После closesocket осталась возможность успешной отправки пакета!!!
Ммм... Мне кажется, что не мешает более плотно изучить теорию. shutdown() перед этим выполняем?
По поводу памяти. То, что она у тебя не отдает память системе, так это вполне нормально. После free() память тоже не всегда сразу отдается системе. И это логично. Так работает менеджер памяти. Программа может вновь ее затребовать для выполнения некоторых операций. Т.е. если ее выделить, потом освободить, а потом - снова выделить, то значительно упадет производительность. А так - выделить надо только один раз. Если у системы будет недостаточно памяти для других нужд, то конечно она заберет эту память у программы сразу.
В общем free() (и т.п.) не обязана сразу выкидывать память в свободный пул системы. Она просто показывает твоей проге что эту память уже можно заюзать для других целей.
После free() память тоже не всегда сразу отдается системе.
...
В общем free() (и т.п.) не обязана сразу выкидывать память в свободный пул системы. Она просто показывает твоей проге что эту память уже можно заюзать для других целей.
Где подчерпнуты эти сведения?
Где подчерпнуты эти сведения?
Уже не помню из какой книжки + проверка на практике. Выделяем дофига памяти, смотрим на прогу хотя бы тем же диспетчером - объем памяти потребляемый программой вырос. Освобождаем эту память - объем практически не падает, если имеется свободная память.
В общем free() (и т.п.) не обязана сразу выкидывать память в свободный пул системы. Она просто показывает твоей проге что эту память уже можно заюзать для других целей.
Впринципе я и сам так думал, но меня мучает слудующий факт. Вот я создал сокет. Закрываю его. closesocket() типа сказал "всё ОК". Память теоретически освободилась, просто Винда оставила её за моей прогой, на случай если она (память) ей снова понадобиться. Тперь я создаю точно такой же сокет. Вместо того, чтобы заюзать только что "оставленную про запас" память, Винда выделяет проге новую память. Почему Винда не заюзала "оставленную про запас" память ???
При многократном циклическом прогоне занимаемая прогой память растёт довольно быстро. При хорошей нагрузке мой http-сервер минут за 20 может занять метров 30 !!!
Вместо того, чтобы заюзать только что "оставленную про запас" память, Винда выделяет проге новую память. Почему Винда не заюзала "оставленную про запас" память ???
При многократном циклическом прогоне занимаемая прогой память растёт довольно быстро. При хорошей нагрузке мой http-сервер минут за 20 может занять метров 30 !!!
Это уже хуже :) Надо подумать.
Это уже хуже :) Надо подумать.
Действительно что-то загадочное. Так и есть. Правда ХЗ, сколько у тебя коннектов за 20 минут может быть. Может все же где-то лага в коде, т.к. у меня после 4000 с небольшим коннектов сервер подрос на 600 Кб. Что конечно не есть хорошо, но и не фатально. Лопату вам в руки. Нам будет интересно, если раскопаешь.
Если раскопаю я, то конечно подскажу.
Действительно что-то загадочное. Так и есть. Правда ХЗ, сколько у тебя коннектов за 20 минут может быть. Может все же где-то лага в коде, т.к. у меня после 4000 с небольшим коннектов сервер подрос на 600 Кб. Что конечно не есть хорошо, но и не фатально. Лопату вам в руки. Нам будет интересно, если раскопаешь.
Если раскопаю я, то конечно подскажу.
насчёт 20 минут я скзал весьма приблизительно.
600 000 / 4 000 = 1 500 байт/сокет - именно такую цифру видел на каком-то сайте, там было написано, что сокеты столько жрут памяти.
Странно, что не могу найти форум, где эту тему подымали до меня :(
600 000 / 4 000 = 1 500 байт/сокет - именно такую цифру видел на каком-то сайте, там было написано, что сокеты столько жрут памяти.
А у тебя сколько получается? Так же? Тогда точно надо ковырять сокеты.
А у тебя сколько получается? Так же? Тогда точно надо ковырять сокеты.
У меня столько, сколько я писал ранее. Возможно я чего-то не учёл (464 и 728).
А про полтора килобайта я где-то ранее читал.
У меня столько, сколько я писал ранее. Возможно я чего-то не учёл (464 и 728).
А про полтора килобайта я где-то ранее читал.
Я немного подраздуплился.
Обычный сокет закрывается нормально с освобождением памяти.
Код ошибки WSAEINVAL выдаёт вызов closesocket() на сокете, возыращенном функцией accept(). Этот сокет в примерах вроде вообще не закрывают. Но так ведь не годиться. Памяти каждый такой сокет отхватывает 950 байт.