[erlang-questions] Memory leak question

Paul Oliver puzza007@REDACTED
Mon Sep 22 16:08:53 CEST 2008


Hi all,

I've written a test client that starts a number of sockets and
repeatedly sends and receives a static sting from an echo server.
I've noticed some strange behavior with an if statement and was
wondering if someone can tell me why?  The following code seems to
leak memory and processes until my box is hosed:

loop(Sock, Log) ->
	Before = if Log -> now();
				true -> 0
			 end,
	ok = gen_tcp:send(Sock,
<<"01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789">>),
	receive
		{tcp, Sock, _Data} ->
			if Log ->
					[{total, Total}, {processes, Processes} , _, _, _, _, {binary,
Binary}, _, _] = erlang:memory(),
					error_logger:info_msg("tot_mem: ~p, binary: ~p, procs: ~p, time: ~p",
										  [Total, Binary, Processes, timer:now_diff(now(),Before)/1000]);
			   true -> true
			end;
		Error ->
			% Anything other than a data message, print error
			error_logger:error_msg(Error)
	end,
	receive
	after ?MESSAGE_INTERVAL ->
			true
	end,
	loop(Sock, Log).

Example logs:

=INFO REPORT==== 22-Sep-2008::14:53:31 ===
tot_mem: 587049608, binary: 334781944, procs: 171962344, time: 9.685

[snip - box now running out of swap]

=INFO REPORT==== 22-Sep-2008::15:00:23 ===
tot_mem: 1261717856, binary: 874756136, procs: 307929080, time: 23137.121


However, changing the receive/if to:

	receive
		{tcp, Sock, _Data} ->
			[{total, Total}, {processes, Processes} , _, _, _, _, {binary,
Binary}, _, _] = erlang:memory(),
			if Log ->
					error_logger:info_msg("tot_mem: ~p, binary: ~p, procs: ~p, time: ~p",
										  [Total, Binary, Processes, timer:now_diff(now(),Before)/1000]);
			   true -> true
			end;

allows the program to run without leaking anything.

Any help greatly appreciated.

Cheers,
Paul.



More information about the erlang-questions mailing list