struct arena_s {
/* This arena's index within the arenas array. */
/* 在arena数组中,arena的下标. */
unsigned ind;
/*
* Number of threads currently assigned to this arena, synchronized via
* atomic operations. Each thread has two distinct assignments, one for
* application-serving allocation, and the other for internal metadata
* allocation. Internal metadata must not be allocated from arenas
* created via the arenas.extend mallctl, because the arena.<i>.reset
* mallctl indiscriminately discards all allocations for the affected
* arena.
*
* 0: Application allocation.
* 1: Internal metadata allocation.
*/
/*
*当前分配给该竞技场的线程数,通过原子操作同步。每个线程有两个不同的分配,一个用于应用程序服
务分配,另一个用于内部元数据分配。不能从通过竞技场创建的竞技场分配内部元数据。扩展mallctl,
因为竞技场。<i>。Reset mallctl不分青红皂白地丢弃受影响竞技场的所有分配。
* 0:应用程序分配。
* 1:内部元数据分配。
*/
unsigned nthreads[2];
/*
* There are three classes of arena operations from a locking
* perspective:
* 1) Thread assignment (modifies nthreads) is synchronized via atomics.
* 2) Bin-related operations are protected by bin locks.
* 3) Chunk- and run-related operations are protected by this mutex.
*/
/*
*从锁定的角度来看,有三种类型的arena操作:
* 1)线程分配(修改nthreads)通过原子同步。
* 2)与bin相关的操作由bin锁保护。
* 3)chunk和run相关的操作被这个互斥锁保护。
* /
malloc_mutex_t lock;
arena_stats_t stats;
/*
* List of tcaches for extant threads associated with this arena.
* Stats from these are merged incrementally, and at exit if
* opt_stats_print is enabled.
*/
/*
*与此arena相关的现存线程缓存列表。
*如果opt_stats_print被启用,这些统计数据将被合并,并在退出时合并。
*/
ql_head(tcache_t) tcache_ql;
uint64_t prof_accumbytes;
/*
* PRNG state for cache index randomization of large allocation base
* pointers.
*/
/*
*大分配基指针缓存索引随机化的PRNG状态。
*/
size_t offset_state;
dss_prec_t dss_prec;
/* Extant arena chunks. */
/*现存arena块。*/
ql_head(extent_node_t) achunks;
/* Extent serial number generator state. */
/*范围序列号生成器状态。*/
size_t extent_sn_next;
/*
* In order to avoid rapid chunk allocation/deallocation when an arena
* oscillates right on the cusp of needing a new chunk, cache the most
* recently freed chunk. The spare is left in the arena's chunk trees
* until it is deleted.
*
* There is one spare chunk per arena, rather than one spare total, in
* order to avoid interactions between multiple threads that could make
* a single spare inadequate.
*/
/*
为了避免在arena需要新块的时候快速分配/释放块,缓存最近释放的块。空间将保留
在arena的chunk树中,直到被删除。
*
*每个arena有一个备用块,而不是一个备用块,以避免多个线程之间的交互可能导致单个备用不足。
*/
arena_chunk_t *spare;
/* Minimum ratio (log base 2) of nactive:ndirty. */
ssize_t lg_dirty_mult;
/* True if a thread is currently executing arena_purge_to_limit(). */
/*如果线程正在执行arena_purge_to_limit(),则为True。* /
bool purging;
/* Number of pages in active runs and huge regions. */
/*活动run和大区域的页面数。*/
size_t nactive;
/*
* Current count of pages within unused runs that are potentially
* dirty, and for which madvise(... MADV_DONTNEED) has not been called.
* By tracking this, we can institute a limit on how much dirty unused
* memory is mapped for each arena.
*/
/*
*当前未使用的runs中可能是脏的页面的计数,因此我建议(…)MADV_DONTNEED)没有被调用。
通过跟踪这一点,我们可以对每个竞技场映射多少未使用的脏内存设置限制。
*/
size_t ndirty;
/*
* Unused dirty memory this arena manages. Dirty memory is conceptually
* tracked as an arbitrarily interleaved LRU of dirty runs and cached
* chunks, but the list linkage is actually semi-duplicated in order to
* avoid extra arena_chunk_map_misc_t space overhead.
* arena管理未使用的脏内存。脏内存在概念上被跟踪为脏Run和缓存chunk的任意交错的LRU,但列表链
* 接实际上是半重复的,以避免额外的arena_chunk_map_misc_t空间开销。
*
* LRU-----------------------------------------------------------MRU
*
* /-- arena ---\
* | |
* | |
* |------------| /- chunk -\
* ...->|chunks_cache|<--------------------------->| /----\ |<--...
* |------------| | |node| |
* | | | | | |
* | | /- run -\ /- run -\ | | | |
* | | | | | | | | | |
* | | | | | | | | | |
* |------------| |-------| |-------| | |----| |
* ...->|runs_dirty |<-->|rd |<-->|rd |<---->|rd |<----...
* |------------| |-------| |-------| | |----| |
* | | | | | | | | | |
* | | | | | | | \----/ |
* | | \-------/ \-------/ | |
* | | | |
* | | | |
* \------------/ \---------/
*/
arena_runs_dirty_link_t runs_dirty;
extent_node_t chunks_cache;
/* Decay-based purging state. */
/*基于衰变的清除状态*/
arena_decay_t decay;
/* Extant huge allocations. */
/*现存的巨大分配。*/
ql_head(extent_node_t) huge;
/* Synchronizes all huge allocation/update/deallocation. */
/*同步所有巨大的分配/更新/释放。*/
malloc_mutex_t huge_mtx;
/*
* Trees of chunks that were previously allocated (trees differ only in
* node ordering). These are used when allocating chunks, in an attempt
* to re-use address space. Depending on function, different tree
* orderings are needed, which is why there are two trees with the same
* contents.
*/
/*
*先前分配的块的树(树只在节点顺序上不同)。这些在分配块时使用,试图重用地址空间。根据不同的功
*能,需要不同的树顺序,这就是为什么有两个具有相同内容的树。
*/
extent_tree_t chunks_szsnad_cached;
extent_tree_t chunks_ad_cached;
extent_tree_t chunks_szsnad_retained;
extent_tree_t chunks_ad_retained;
malloc_mutex_t chunks_mtx;
/* Cache of nodes that were allocated via base_alloc(). */
/*通过base_alloc()分配的节点缓存。*/
ql_head(extent_node_t) node_cache;
malloc_mutex_t node_cache_mtx;
/* User-configurable chunk hook functions. */
/*用户可配置的块钩子函数。*/
chunk_hooks_t chunk_hooks;
/* bins is used to store trees of free regions. */
/* bins用于存储空闲区域的树。*/
arena_bin_t bins[NBINS];
/*
* Size-segregated address-ordered heaps of this arena's available runs,
* used for first-best-fit run allocation. Runs are quantized, i.e.
* they reside in the last heap which corresponds to a size class less
* than or equal to the run size.
*/
/*
* size - segregation - address-ordered堆这个arena的可用runs,用于第一最适合的run分配。
* runs是量化的,即它们驻留在最后一个堆中,该堆对应的大小类小于或等于B的大小。
*/
arena_run_heap_t runs_avail[NPSIZES];
}