Advice wanted on garbage collection of sockets for c++ programmer using D

Jonathan M Davis via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Tue Jun 27 03:14:16 PDT 2017


On Tuesday, June 27, 2017 09:54:19 John Burton via Digitalmars-d-learn 
wrote:
> I'm coming from a C++ background so I'm not too used to garbage
> collection and it's implications. I have a function that creates
> a std.socket.Socket using new and connects to a tcp server, and
> writes some stuff to it. I then explicitly close the socket, and
> the socket object goes out of scope.
>
> I assume that I do need to explicitly call close on the socket as
> there is no deterministic destructor for class objects. I further
> assume that the runtime will garbage collect any memory allocated
> to the socket object at a later time.
>
> Am I doing this right with GC? In C++ I'd ensure that the Socket
> class had a destructor that closed the socket and I'd also assume
> that once it went out of scope there was no memory left
> allocated. In D am I right to assume I need to manually close the
> socket but there is no need to worry about the memory?
>
> Now the issue is that I now need to call this function more than
> once every second. I worry that it will create large amounts of
> uncollected "garbage" which will eventually lead to problems.
>
> Am I doing this right? Or is there a better way to do this in D?

Arguably, std.socket should have used structs instead of classes for sockets
for precisely this reason (though there are some advantages in using
inheritance with sockets). But yes, calling close manually is the correct
thing to do. Relying on the GC to call a destructor/finalizer is
error-prone. There is no guarantee that the memory will ever be freed (e.g.
the runtime could choose to not bother doing cleanup on shutdown), and even
if the GC does collect it, there are no guarantees about how soon it will do
so. However, if you keep allocating memory with the GC, then over time, the
GC will collect GC-allocated memory that isn't currently being used so that
it can reuse the memory. So, you really don't need to worry about the memory
unless it becomes a bottleneck. It will be collected and reused, not leaked.

And if in C++, you would be newing up a socket object each time and then
deleting it rather than having the socket on the stack, then that
performance could actually be worse than using the GC and having it collect
the memory when it determines that it needs more memory.

If you do find that it becomes a bottleneck to be allocating all of these
sockets, then you can look into using std.typecons.scoped, which would
allocate a class on the stack, but that really only works if you're just
dealing with a local variable, and in general, I wouldn't worry about
anything like that unless the heap allocations are proving to be a
performance problem - particularly because you need to be very careful when
using it to avoid screwing up and having memory corruption, because you used
an object after it was freed.

- Jonathan M Davis



More information about the Digitalmars-d-learn mailing list