slow runtime

Jonathan M Davis jmdavisprog at gmail.com
Fri Sep 10 20:23:43 PDT 2010


On Friday 10 September 2010 19:40:10 Andrej Mitrovic wrote:
> What about gc.disable() and gc.enable() ? If I'm sure that I won't
> allocate anything within a section of code and I have to guarantee
> realtime performance, then I could disable the gc temporarily.
> Although this is not exactly what it states in the section on memory
> management:
> 
> "Call std.gc.disable() before the smooth code is run, and
> std.gc.enable() afterwards. This will cause the GC to favor allocating
> more memory instead of running a collection pass."
> 
> Is the gc disabled after the call to gc.disable(), or just relaxed? If
> it's not disabled, then I'm not sure why it's named like that.
> 
> On Sat, Sep 11, 2010 at 4:28 AM, Jonathan M Davis <jmdavisprog at gmail.com> 
wrote:
> > snip

I'm really not all that well informed about the ins and outs of D's GC and 
trying to minimize its negative effects. The programs that I write care far more 
about stuff other than realtime performance for me to go to the effort of trying 
to avoid the GC (especially since that can seriously complicate a program). 
However, from the sound of it, std.gc.disable() is arguably poorly name.

It obviously doesn't disable the GC completely. new isn't going to start using 
the manual heap or stop working. It sounds like it doesn't even necessarily 
disable garbage collection from occurring. My _guess_ would be that what it does 
is make it so that the GC will allocate memory from the OS if it doesn't have 
enough free memory in its pool, and if that fails, run a garbage collection 
cycle to recover memory (since it's either that throw an OutOfMemoryError - or 
whatever the exception is called exactly - which would kill the program), but I 
don't know. Certainly, I believe that normally the GC will run a cycle if it's 
low on free memory in its pool, and then get memory from the OS only if it has 
to, and if you have called std.gc.disable(), it's not going to be as quick to 
run a garbage collection cycle. But obviously the documentation does not make it 
clear enough what _would_ make it run a garbage collection cycle if 
std.gc.disable() has been called.

In any case, if you're looking to avoid GC collection cycles, it sounds like 
std.gc.disable() and std.gc.enable() will help. But remember that that will 
increase the odds that it will have to allocate more memory from the OS, which 
isn't cheap either. It's almost certainly cheap_er_, but it still wouldn't be 
cheap. Also, with D's current GC, that means that your program will use more 
memory overall. Not only will you not be using perfectly useable memory from the 
GC heap (since it won't have been collected yet), but it will allocate more 
memory to the heap, and the GC's current implementation never gives that memory 
back to the OS. So, overall memory usage will increase.

So, odds are that the best bet would be to avoid allocations in critical 
sections and call std.gc.disable() before entering them and std.gc.enable() when 
you exit them. But you probably should get input from one of the D GC gurus if 
you really want to know the absolute best way to reduce the impact of the GC in 
critical sections.

However, I would point out, as I said before, that on today's systems, odds are 
that you will get properly realtime performance in spite of the GC and any 
collection cycles that it runs. D's GC being more primitive may not do as good a 
job with that as others - like Java's or .NET's - but I'm not sure that you want 
to complicate your program worrying about the GC unless you profile it 
appropriately and find out that you need to. Certainly, as D matures, it should 
become less of an issue.

- Jonathan M Davis


More information about the Digitalmars-d-learn mailing list