texmacs-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Texmacs-dev] Boehm-gc-texmacs gc behavior (was: Re: Boehm-gc-texmac


From: David Allouche
Subject: Re: [Texmacs-dev] Boehm-gc-texmacs gc behavior (was: Re: Boehm-gc-texmacs cache behavior)
Date: Mon, 24 May 2004 12:50:18 +0200
User-agent: Mutt/1.5.5.1+cvs20040105i

On Sun, May 23, 2004 at 08:51:44PM +0200, David MENTRE wrote:
> David MENTRE <address@hidden> writes:
> 
> > Subjectively, texmacs seems to have the same interactivity but your
> > right, memory consumption is doubled (resident size of 74 MB against
> > about 35 MB for a standard texmacs). This is quite strange. Or there is
> > a bad side effect, like a bad interaction between libgc and guile. E.g.,
> > would it be possible that guile keeps pointers on memory that would have
> > to be reclaimed? Should Guile be also built with the GC?
> 
> Ok. Digging into Boehm GC docs, I found the following:
> http://www.hpl.hp.com/personal/Hans_Boehm/gc/debugging.html
> 
> *Unexpectedly Large Heap*
> 
> Unexpected heap growth can be due to one of the following:
> 
>    1. Data structures that are being unintentionally retained. This is
>       commonly caused by data structures that are no longer being used,
>       but were not cleared, or by caches growing without bounds.

Unused-but-not-cleared structures affect pointer counting even more than
garbage collection, so I have assumed this was not a problem in the code
base.

The important caches I identified were the "Resource" things. Generally,
the pointer counting for this data is broken and they are never
collected. I have put a lot of work it making them collectable and
fixing dormant bugs. Eventually, it did not seem to make a big
difference on performance, and caused the console output to be
considerably more verbose as the same resources were repeatedly loaded
and freed.

> For (1), I can't tell. Would it be possible to have "caches growing
> without bounds"? 

A common memory-leak pattern with conservative GC which might be alluded
to there:

  * an infinitely growing data structure, like a stream (in the Scheme
    sense) or a FIFO.
  
  * under normal circumstances, only a tail of the structure is ever
    accessible, so the memory consumption is bounded

  * conservative GC causes _one_ cell of the structure to be retained,
    because some random data is mistaken for a pointer to that cell.

  * if references from discarded cells are not cleared, then the
    memory consumption is now unbounded

Once the problem is pinned down, it's easy to fix. I do not think that
TeXmacs is using such an infinite data structure in its collectable
data.

Also I did not notice an unbounded memory consumption, only a very large
overhead, so I am inclined to think the problem is not there. Yet one
can imagine some patterns when such a problem would have effects which
are not distinguishable from a simple overhead, I do not think it is
worth considering in the absence of empirical evidence.


>    2. Pointer misidentification. The garbage collector is interpreting
>       integers or other data as pointers and retaining the "referenced"
>       objects. A common symptom is that GC_dump() shows much of the heap
>       as black-listed.

That could be worth checking. I have not been using GC_dump(), but I
have tried to grab most of the low-hanging fruits.

See patch-14: "atomic allocation where possible"

The rectangle, string, space, tag_info, bitmap_font, etc. data which is
known not to contain pointers is allocated as atomic data and is not
considered when looking for accessible references.

The only glaring omission here, is list_rep data, but it cannot be
marked atomic since the same allocation block contain both the data
pointer and next cell pointer. One could go through the hoops (and extra
indirections) required to make the data part atomic when applicable,
using the same template logic as in array_rep, I have just not tried.


> For (2), I take a look at GC_dump() (by setting env var
> GC_DUMP_REGULARLY). It appears that about 35 MB is partially
> black-listed. This would explain the x2 memory overhead. I don't know
> what this partially means.
> 
> Free list 60 (Total size 36118528):
>       0x96a9000 size 1077248 not black listed
>       0x9edc000 size 35041280 partially black listed
> Total of 60502016 bytes on free list
> 
>  (see a more complete detail below).
> 
> It would be interesting to know what resides at address 0x9edc000.
> 
> So (2) is a candidate explanation.

Sounds intriguing.

Another interpretation is that everything is all right. The blacklisted
35MB is the usual memory consuption of TeXmacs.


>    3. Heap fragmentation. This should never result in unbounded growth,
>       but it may account for larger heaps. This is most commonly caused
>       by allocation of large objects. On some platforms it can be
>       reduced by building with -DUSE_MUNMAP, which will cause the
>       collector to unmap memory corresponding to pages that have not
>       been recently used.

I have not investigated that.

Generally I have avoided features that rely on specific build-time flags
because I think they are likely to cause confusion when packaged in
binary distributions (Debian, RedHat) which use a single libgc shlib
build.

> For (3), I can't tell. Is texmacs allocating large objects?

Depends on what you call large, but I'd rather say no. Well there can be
a few large objects (resources, structures relating to the top DOCUMENT
node of large documents). But programmers are notoriously bad at
guessing the allocation patterns of their programs.

Empirical data would be useful here. You can gather that data by
modifying the custom allocator on a non GC-enabled texmacs.


>    4. Per object overhead. This is usually a relatively minor effect,
>       but it may be worth considering. If the collector recognizes
>       interior pointers, object sizes are increased, so that
>       one-past-the-end pointers are correctly recognized. The collector
>       can be configured not to do this (-DDONT_ADD_BYTE_AT_END).

That might be a significant overhead, since texmacs uses many many small
structures like tree_rep (and descendants), list_rep, array_rep,
string_rep and whatnot.

Once again, removing uneeded indirections would reduce that overhead.

> For (4), I can't tell but I wouldn't choose it as first candidate. 

Certainly not a first candidate, but it might account for a significant
part of the problem.

> I hope it lights a candle in this GC dark. :) But as you have done the
> port, only you David can tell what is going wrong.

There is probably still ample room for improvement in the GC support,
but, by it's very nature, GC is expensive in memory compared to pointer
counting. It needs some slack to avoid making too frequent collections.
Yet there may be a few simple problems which I have not spotted and that
would be really aggravating.

The improvements I have in mind were described in the profiling
thread.

The controls I have used for tweaking the collector performance are in
tune_gc() in texamcs.cpp.

> PS : details on the last GC pass:

Mhh... look like there is really a bunch of big memory blocks around.
Really intriguing.

Another usual suspect I have forgotten about: the file I/O. It's
implemented using whole file reads and writes. More lazy i/o could be
nicer on the allocator and cpu cache.

Yet that pattern of many big blocks of the same size is not explained by
file i/o... I do not know.

-- 
                                                            -- ddaa




reply via email to

[Prev in Thread] Current Thread [Next in Thread]