diff --git a/jemalloc/doc/jemalloc.3.in b/jemalloc/doc/jemalloc.3.in index efe773bd..f55325e8 100644 --- a/jemalloc/doc/jemalloc.3.in +++ b/jemalloc/doc/jemalloc.3.in @@ -312,6 +312,15 @@ Double/halve the size of the maximum size class that is a multiple of the quantum (8 or 16 bytes, depending on architecture). Above this size, cacheline spacing is used for size classes. The default value is 128 bytes. +@roff_tcache@.It S +@roff_tcache@Sort the objects of a particular size class that are stored in a +@roff_tcache@thread-specific cache just before flushing some of them from the +@roff_tcache@cache, such that the objects highest in memory are preferentially +@roff_tcache@freed. +@roff_tcache@This tends to reduce fragmentation, but sorting is (n lg n), and in +@roff_tcache@practice it is expensive enough to have a moderate performance +@roff_tcache@impact. +@roff_tcache@This option is enabled by default. @roff_trace@.It T @roff_trace@Write a verbose trace log to a set of files named according to the @roff_trace@pattern diff --git a/jemalloc/src/jemalloc.c b/jemalloc/src/jemalloc.c index 71db5199..9fe90423 100644 --- a/jemalloc/src/jemalloc.c +++ b/jemalloc/src/jemalloc.c @@ -1090,6 +1090,7 @@ static bool opt_junk = false; #ifdef JEMALLOC_TCACHE static size_t opt_lg_tcache_nslots = LG_TCACHE_NSLOTS_DEFAULT; static ssize_t opt_lg_tcache_gc_sweep = LG_TCACHE_GC_SWEEP_DEFAULT; +static bool opt_tcache_sort = true; #endif static ssize_t opt_lg_dirty_mult = LG_DIRTY_MULT_DEFAULT; static bool opt_stats_print = false; @@ -4058,7 +4059,7 @@ tcache_bin_flush(tcache_bin_t *tbin, size_t binind, unsigned rem) void *ptr; unsigned i, ndeferred, ncached; - if (rem > 0) { + if (opt_tcache_sort && rem > 0) { assert(rem < tbin->ncached); /* Sort pointers such that the highest objects will be freed. */ tcache_bin_sort(tbin); @@ -5696,6 +5697,14 @@ MALLOC_OUT: opt_lg_cspace_max) opt_lg_qspace_max++; break; +#ifdef JEMALLOC_TCACHE + case 's': + opt_tcache_sort = false; + break; + case 'S': + opt_tcache_sort = true; + break; +#endif #ifdef JEMALLOC_TRACE case 't': opt_trace = false; @@ -6418,6 +6427,9 @@ malloc_stats_print(const char *opts) malloc_message(opt_junk ? "J" : "j", "", "", ""); #endif malloc_message("P", "", "", ""); +#ifdef JEMALLOC_TCACHE + malloc_message(opt_tcache_sort ? "S" : "s", "", "", ""); +#endif #ifdef JEMALLOC_TRACE malloc_message(opt_trace ? "T" : "t", "", "", ""); #endif