-
Есть такая процедура: procedure Check(); var Socket: TSocket; begin Socket := WinSock.socket(PF_INET, SOCK_STREAM, 0);
WinSock.shutdown(Socket, SD_BOTH);
WinSock.closesocket(Socket); end;
осуществляем проверку и вызываем ее 1000 раз: for Index := 1 to 1000 do Check();
получаем утечку памяти на 142-152 KB за проверку. Т.е. 10 проверок = 10000 вызовов Check = 1.5 MB.
Кто-нибудь знает как устранить это явление?
-
что-то не ясно как из этого кода определили утечку?
-
Диспетчер задач Windows и TaskInfo. Программа имеет только этот код, так что никаких дополнительных операций нет
-
В дополнение. Это код у клента. К серверу коннектится. И вопрос к утечке памяти у клиента
-
MSDN: closesocked(SOCKET) finction [Winsock] ... Here is a summary of closesocket behavior:
If SO_DONTLINGER is enabled (the default setting) it always returns immediately???connection is gracefully closed in the background.
If SO_LINGER is enabled with a zero time-out: – it always returns immediately — connection is reset/terminated.
If SO_LINGER is enabled with a nonzero time-out: – with a blocking socket, it blocks until all data sent or time-out expires. – with a nonblocking socket, it returns immediately indicating failure.
- реже долбиться надо...
-
Спасибо! Буду пробовать...
-
НЕ РАБОТАЕТ! 1) добавил после создания сокета Linger.l_onoff := 0; Linger.l_linger := 0; WinSock.setsockopt(Socket, SOL_SOCKET, SO_LINGER, PAnsiChar(@Linger), SizeOf(Linger)); Значение опции устанавливается, но результат тот же
2) -"- Linger.l_onoff := 0; Linger.l_linger := 0; WinSock.setsockopt(Socket, SOL_SOCKET, SO_DONTLINGER, PAnsiChar(@Linger), SizeOf(Linger)); // возвращает ошибку WSAENOPROTOOPT
-
К стати, чтобы "реже долбиться", следал задержку после закрытия сокета на 100 мсек. Эффект - тот же :(
-
память выделенная программе <> потерянная (утечка) выделяется чаще из "чистой" области, так проще и быстрее, что и является главной целью, а не минимизация в отображении диспетчере задач. отдается не сразу, а по запросу, или если нет свободной в запросе на выделение. чтобы сравнивать нужно "добиться" перераспределения памяти, с очисткой уже свободной но еще не отданной в "общий пул", например свернув программу в панель задач (в этот момент делается как бы "уборка программы на хранение" с перераспределением памяти), ну или выполняя функцию которой это делается там.
p.s. в инете куча статей типа "почему не нужно смотреть память в диспетчере задачь"
-
Прикол состоит в том, что это все "от лукавого". Я смотрю по TaskInfo, это указано выше. Я это использовал всегда - вопросов не было. Проект, в котором это используется - старый и огромный (исходных текстов на 50МБ), и там, все остальное, корректно байт в байт.
-
> получаем утечку памяти на 142-152 KB за проверку У меня нет никаких утечек - ни за одну "проверку", ни даже за один проход цикла Да, есть прирост воркингсета на 16 кб за 1-й же проход цикла. Те же 16 кб прироста фигурируют при любом кол-ве "проверок". И это совершенно нормально и никакой "утечкой" не является. http://zalil.ru/30567596program Job;
uses
CRT, Winsock;
procedure Check();
var
Socket: TSocket;
begin
Socket := WinSock.socket(PF_INET, SOCK_STREAM, 0);
WinSock.shutdown(Socket, SD_BOTH);
WinSock.closesocket(Socket);
end;
var
i: Integer;
begin
for i := 1 to 1000 do Check;
ReadKey;
end.
Что я неправильно делаю ?)
-
Повторил Ваш пример. У меня TaskInfo и TaskManager показывают одинаково - до 1716КБ до и 1728 КБ после.
Для цикла в 10000, данные такие: до 1716КБ до и 1728 КБ после. Прироста нет. :) Но мой тест ранее был в GUI. Один и тот жет тест в GUI и консоле дает разные результаты. :) Проверю еще...
К стати, здесь shutdown вызывать не нужно, т.к. еще нет соединения и вызов не отрабаотывается и возврашает SOCKET_ERROR.
-
> Один и тот жет тест в GUI и консоле дает разные результаты
Какие бы ни давал, но к утечкам в Winsock (по кр.мере применительно к тестируемой логике) он не имеет ни малейшего отношения.
-
В Вашем примере сокет вообще не создается (Socket = -1) - не инициализорована библиотека сокетов. Поэтому и нет никакой утечки. Попробуйте так: program Project1;
uses
SysUtils, WinSock;
procedure Check();
var voSocket: TSocket;
begin
voSocket := WinSock.socket(PF_INET, SOCK_STREAM, 0);
WinSock.closesocket(voSocket);
end;
var voWSAData: TWSAData;
viIndex: integer;
begin
WSAStartup($0201, voWSAData);
ReadLn;
for viIndex := 1 to 1000 do Check();
ReadLn;
WSACleanup();
end.
-
> Попробуйте так: запускаю, занято памяти в таск менеджере = 1744 байт неактуально (см [8]) делаю сворачивание/разворачивание программки = 92 байта... берем за точку отсчета нажимаю ентер в программе (первый "ридлайн") = 1036 байт неактуально (см [8]) сворачивание/разворачивание = 92 байта... ??? вы про какую утечку?
-
пробуй, хотя процедура чуть не так работает как сворачивание (не полностью), видать еще нужно не просто убрать неиспользуемое с конца, но и перераспределить чтобы убрать фрагментацию в использованном. ну, да все одно показатель. program Project1;
uses
Windows,
SysUtils,
WinSock;
procedure Check();
var voSocket: TSocket;
begin
voSocket := WinSock.socket(PF_INET, SOCK_STREAM, 0);
WinSock.closesocket(voSocket);
end;
var
voWSAData: TWSAData;
viIndex: integer;
begin
WSAStartup($0201, voWSAData);
SetProcessWorkingSetSize(GetCurrentProcess, dword(-1), dword(-1));
ReadLn;
for viIndex := 1 to 1000 do Check();
SetProcessWorkingSetSize(GetCurrentProcess, dword(-1), dword(-1));
ReadLn;
WSACleanup();
end. p.s. кстати не советую применять функцию в реальных программах, для "минимизации памяти", только тормозов добавишь, если например не кстати, случайно попадет в цикл/пересекеться с менеджером памяти.
-
> DmitryA (26.02.11 13:29) [13] > > В Вашем примере сокет вообще не создается
Процедуру чека я содрал один в один из твоего 1-го поста, там где собственно и зашла речь об утечке
-
> DmitryA (24.02.11 14:45) [2] > > Диспетчер задач Windows и TaskInfo. Программа имеет только > этот код, так что никаких дополнительных операций нет
ну дык это не говорит об утечке, не так ли?
по идее нужно определить количество выделенной и освобожденной памяти, чтобы выяснить если ли утечка.
менеджер памяти запускает сборщик мусора, после чего память освобожденная в программе, должна стать доступна другим программам.
Как вариант можно попробовать запустить другую программу выделяющую большое количество памяти, и посмотреть уменьшился ли объем выделенной памяти в первой программе.
-
> менеджер памяти запускает сборщик мусора это в дельфе то?
> Как вариант можно попробовать запустить другую программу ... товарищ писатель, может, как вариант, попробуешь почитать ветку? где уже все объяснено и даны методы более очевидные и наглядные чем тот бред который вы предлагаете.
-
> sniknik © (27.02.11 01:16) [18]
А ты мне номер телефона оставь, я буду звонить тебе и спрашивать как поступить!
|