Disadvantages of ARC

Johannes Pfau nospam at example.com
Thu Feb 6 07:47:05 PST 2014


Am Thu, 6 Feb 2014 14:37:59 +0300
schrieb Max Klyga <max.klyga at gmail.com>:

> 
> My point is that we should not ruin the language ease of use. We do 
> need to deal with Phobos internal allocations, but we should not
> switch to ARC as a default memory management scheme. 

What's with all this finger pointing and drawing battle lines in the
last few days? GC-crowd vs ARC-crowd? Can we please all calm down?

Who even proposed to replace the GC completely with ARC? Can somebody
point me to a clear statement demanding that?

90% of phobos isn't actually affected by the ARC/GC issue. Most
functions just allocate memory, then return some result and are
finished. They do not keep data references. As they do not keep
references there's no need for ARC or GC, we just need a way to tell
every function how it should allocate.

Some people seem to want some implicit way to set a 'default'
allocator, but I haven't heard of any solution that works. (E.g. having
a thread-local default allocator, per library default allocator, how
would that even work?)

I don't think there's anything wrong with the obvious solution: All
phobos functions which allocate take an optional Allocator parameter,
defaulting to GC. The little extra typing won't harm anyone and if you
want to use things like stack-based buffers you'll have to write extra
code and think about memory allocation anyway.

auto gcString = toUpper("test");
auto mallocString = toUpper!Malloc("test");
ubtye[64] sbuf;
auto stackString = toUpper(sbuf[], "test");

What's so bad about this? It works for most of phobos, doesn't require
language changes and it's easy to realize what's going on when reading
the code. Having an 'application default allocator' or 'thread local
default allocator' or 'per function default allocator' will actually
hide the allocation strategy and I bet it would cause issues.


So the question then is: what about language feature which allocate
using the GC? Wouldn't we want these to work with any kind of
allocator? Answer: no, because:

This is the list of language features which allocate:

* .sort, .idup, .dup, setting .length

Sort is deprecated; we should provide duplicate!Allocator functions as
a replacement for dup/idup (Or dup/idup could support an allocator
argument); just don't set .length. If you need some way to grow an
Array just use Appender or a library array, ...

* closures

Who needs these anyway? If the callees only use scoped delegates
closures do not allocate. Otherwise just implement the closure
yourself and allocate wherever you want:

int localA, localB;
struct Frame
{
    int a, b;
    int callback() {a++};
}
auto f = allocate!(Frame, Malloc)(localA, localB);
functionWithDelegate(&f.callback);

* ~, ~= on slices (not on user types)

Just avoid these. When string processing a call to format!Allocator
would be better anyway. For other stuff use Appender!Allocator or some
other library type which could actually overload ~,~= and then you can
use these again...

* delete

deprecated

* new

we need a generic allocation function anyway, allocate!Allocator

* Array literals
* Associative array literals (not in all cases)

That should be fixed. I hope at some point these types will be
implemented in druntime/phobos, support allocators and don't need
TypeInfo. Until then, just use user defined Array, AssociativeArray
types.


I think with relatively little effort we could solve most problems. The
remaining cases must be decided on a case-by case basis. Should
containers use RC or GC, some stuff like that.

Exceptions currently can't work on a system without GC cause we always
use 'throw new' and nobody ever explicitly frees Exceptions. ARC could
be a solution to that issue (if we enforce that exceptions may not have
circular references, but they shouldn't anyway)

And then slices which are actually stored by functions are another
issue.

But it's not like we just change the whole language to ARC. We already
have forced RC in phobos: std.stdio.File for example. And nobody
complained, except that RefCounted has bugs and an ARC implementation
for File could avoid these bugs and be faster than the current
implementation...

We just have to provide everyone with a way to choose their favorite
implementation. Which means we provide public APIs which allow any kind
of memory allocation and internally do not rely on automatic memory
management (internal allocation in phobos should be done on the stack/
with malloc / made configurable, but not with a GC).


More information about the Digitalmars-d mailing list