Reading from network sockets appears to cause massive amounts of memory allocation.
Does anyone know why? Is this a bug?
raw_data = Vector{UInt8}(undef, message_length)
read!(socket, raw_data)
What I find strange is that the object into which data is written is preallocated with a known length. So there shouldn’t be any allocation taking place here.
What I see is that the number of allocations is approximately the same as the number of elements.
It may be difficult to reproduce this. I can’t provide the original code in its entirety. I have been able to reproduce it by writing small chunks of data to a socket, while the reading end is waiting for a much larger block of memory to complete.
Good numbers to use are an array of 1 million integers.
using Sockets
sock = Sockets.connect(IPv4("127.0.0.1"), 22222)
v = Vector{Int64}(undef, 1000000)
read!(sock, v)
Sending side:
using Sockets
server = Sockets.listen(IPv4("127.0.0.1"), 22222)
socket = accept(server)
for i in 1:1000
v = Vector{Int64}(undef, 1000)
write(socket, v)
end
Set the receiving side to run first, then trigger the sending side.
I think that should be enough to reproduce a similar behaviour.
As far as I am aware, I am not doing something “weird” here. (The documentation on sockets is pretty minimal, so it’s hard to know.)
Perhaps this is just not an idiomatic way to use sockets, and that is the cause of the problem. I have no idea.
I am using --track-allocation=user to track the memory allocation. Here is one line from one of my .mem files.
25530368 raw_data = Vector{UInt8}(undef, msglen - bytes_already_read)
That’s 25 million allocations to read ~ 25 MB of data.
Just some additional tests. This is from julia --track-allocation=user, calling Profile.clear_malloc_data() after running each function once to trigger the JIT, and then calling each function again to obtain measurements.
- function example()
0 v = Vector{Int64}(undef, 1000000)
0 return v
- end
-
- function example2(socket)
8000072 v = Vector{Int64}(undef, 1000000)
0 read!(socket, v)
0 return v
- end