Exhaustive benchmarking of allocators is not feasible, and the benchmark results should not be inter-
preted as definitive in any sense. Allocator performance is highly sensitive to application allocation
patterns, and it is possible to construct microbenchmarks that show any of the three allocators tested
here in either a favorable or unfavorable light, at the benchmarker’s whim. I made every attempt to
avoid such skewing of results, but my objectivity should not be assumed by the reader. That said, the
benchmarks should be sufficient to convince the reader of at least the following:
• jemalloc’s run time performance scales well for multi-threaded programs running on multi-processor
systems.
• jemalloc exhibits similar performance to phkmalloc and dlmalloc for single-threaded programs,
both in terms of run time and memory usage.
In point of fact, jemalloc performed very well for the presented benchmarks, and I have found no
reasons to suspect that jemalloc would perform substantially worse than phkmalloc or dlmalloc for
anything but specially crafted microbenchmarks.
None of the benchmarks were designed to measure performance under memory pressure. Such
benchmarks would be of interest, but I did not include them here mainly because phkmalloc has been
shown to perform well under memory pressure (Kamp, 1998; Feng and Berger, 2005), and jemalloc
uses sufficiently similar algorithms that it should exhibit similar performance.
Fragmentation was quite difficult to analyze, since it is mainly a qualitative issue, and standard
tools only provide quantitative metrics. Maximum resident memory usage results are only moder-
ately useful when analyzing fragmentation, since differences between allocators indicate differences
in fragmentation at the point of maximum memory utilization. Obviously, an allocator could cause
much worse data locality for the application without having a substantial impact on maximum resi-
dent memory usage.
In order to better understand fragmentation, I wrote a program that processes kdump(1) output
that was generated by using the “U” malloc(3) option in conjunction with ktrace(1). An example
graph is shown in Figure 9. With this program I was able to observe the effects of various layout
policies, and as a result jemalloc uses memory much more effectively than in earlier development
versions.
Understanding allocator performance for various allocation patterns is a constant challenge. Mech-
anisms for gaining insight into what the allocator is actually doing are important both during allocator
development and application development. To this end, jemalloc outputs detailed statistics at exit if
optional code is enabled at libc compile time, and if the “P” malloc(3) option is specified. Following is
output from running the cca benchmark. Detailed interpretation is left to the reader who is interested
enough to read the allocator source code. However, most of the statistics should have obvious meanings
after having read this paper.