On 6/27/17 8:29 AM, Guillaume Piolat wrote:
On Tuesday, 27 June 2017 at 09:54:19 UTC, John Burton wrote:
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?
Yes.
You can also call a destructor manually with destroy(obj);
This avoids having a forest of 'close' methods, who are duplicates of
the destructor in spirit, and let's you use destructors like you are
accustomed in C++.
Generally, it is dangerous to let the GC handle resource release:
https://p0nce.github.io/d-idioms/#The-trouble-with-class-destructors
This is the best to read, it's very tricky for people coming from other
languages I think to understand the rules around the GC destructor.
I think you have gotten sound advice from many people, but I wanted to
chime in as someone who used the GC to clean up sockets and file handles
in a long-running program. Even with all these warnings, it does seem to
work. My advice is to close the socket in the destructor if still valid,
and then manually close it also. This way you don't leak resources if
you miss a close call.
The fundamental problem with closing sockets and other resources with
the GC is that the resource management issues and rules for memory are
vastly different than those of other resources. The OS can give you vast
sums of memory, but will likely limit your ability to keep sockets open.
It also keeps the other end potentially locked up. If you try to
allocate a new socket and run out of sockets, there is no "socket
collection cycle". This is why closing manually is advised.
But I would use a close method, and not destroy(obj). The reason is
because often times, you have wrapper types around your socket type, and
just one extra level of indirection means the destructor cannot be used
to clean up the socket (you are not allowed to access GC-allocated
resources in a destructor).
Using std.typecons.RefCounted also can help to ensure destruction of a
socket when it's no longer used. But like I said, it's not always
possible to use a destructor of a higher level object to clean up a socket.
-Steve