On my Linux system, Libc info documentation states this about
malloc():
Very large blocks (much larger than a page) are allocated with
`mmap' (anonymous or via `/dev/zero') by this implementation.
This has the great advantage that these chunks are returned to the
system immediately when they are freed. Therefore, it cannot
happen that a large chunk becomes "locked" in between smaller ones
and even after calling `free' wastes memory. The size threshold
for `mmap' to be used can be adjusted with `mallopt' [the default
one is 128K --hniksic]. The use of `mmap' can also be disabled
completely.
It seems that our relocating allocator attempts to do what Doug Lea
malloc() already does. The system-provided mmap-based allocation
seems a better idea in XEmacs because it's performed for *all* large
allocations (large vectors, strings, frob blocks etc.) rather than
only for buffers, as our ralloc does.
So I conducted the following test:
1) Allocate a 10M string with
(prog1 nil (setq a (make-string 10000000 ?x)))
2) Allocate a 5M string with
(prog1 nil (setq b (make-string 5000000 ?x)))
3) Remove reference to the first string and garbage collect.
(setq a nil)
(garbage-collect)
4) Remove reference to the second string, the same way.
Sizes of the XEmacs process go like this (size/resident size, as
reported by ps):
Start:
8860 5640
(1)
18644 15444
(2)
23532 20332
(3)
13776 10572
(4)
8892 5692
Obviously, XEmacs grows by 10M, then by 5M more, then shrinks by 10M,
and finally removes to original state. All that memory comes from
strings, on an XEmacs compiled without relocating allocator. To me it
seems that things work as advertised in the manual.
Does this mean we ought to turn off relalloc on Linux for 21.2?