Programing

jemalloc은 어떻게 작동합니까?

crosscheck 2020. 12. 8. 07:43
반응형

jemalloc은 어떻게 작동합니까? 이점은 무엇입니까?


Firefox 3에는 새로운 할당 자 : jemalloc.

이 새로운 할당자가 더 낫다는 것을 여러 곳에서 들었습니다. 상위 Google 결과는 추가 정보를 제공하지 않으며 정확히 어떻게 작동하는지에 관심이 있습니다.


jemalloc"Jason Evans"의 발명품 인 FreeBSD에 처음 등장했습니다. 나는 내가 한 번도 운영 체제를 작성하지 않았다면 이기적이라고 그를 조롱합니다 paxos:-)

자세한 내용은 이 PDF참조 하십시오. 알고리즘 작동 방식을 자세히 설명하는 백서입니다.

주요 이점은 부분적으로 다중 아레나 (할당이 이루어지는 원시 메모리 청크)를 사용하여 달성되는 다중 프로세서 및 다중 스레드 시스템의 확장 성입니다.

단일 스레드 상황에서는 여러 경기장에 실질적인 이점이 없으므로 단일 경기장이 사용됩니다.

그러나 다중 스레드 상황에서는 많은 아레나가 생성되고 (프로세서보다 4 배 많은 아레나) 스레드가 라운드 로빈 방식으로 이러한 아레나에 할당됩니다.

즉, 여러 스레드가 호출 malloc하거나 free동시에 호출 할 수 있지만 동일한 아레나를 공유하는 경우에만 경쟁하기 때문에 잠금 경합을 줄일 수 있습니다 . 아레나가 다른 두 개의 스레드는 서로 영향을주지 않습니다.

또한 jemallocRAM에서 데이터를 가져 오는 작업이 이미 CPU 캐시에있는 데이터를 사용하는 것보다 훨씬 느리기 때문에 캐시 지역성을 최적화하려고합니다 (RAM에서 빠른 가져 오기와 디스크에서 느린 가져 오기의 차이와 개념 상 다르지 않음). 이를 위해 먼저 애플리케이션의 전체 작업 세트가 캐시에 있도록 보장 할 가능성이 높기 때문에 전체 메모리 사용량을 최소화하려고합니다.

그리고 그것을 달성 할 수없는 곳에서는 함께 할당 된 메모리가 함께 사용되는 경향이 있기 때문에 할당이 연속적인지 확인하려고합니다.

백서에서 이러한 전략은 단일 스레드 사용에 대한 현재 최고의 알고리즘과 유사한 성능을 제공하는 동시에 다중 스레드 사용에 대한 개선 사항을 제공하는 것으로 보입니다.


흥미로운 소스가 하나 있습니다. C 소스 자체 : https://dxr.mozilla.org/mozilla-central/source/memory/build/mozjemalloc.cpp ( old )

처음에는 간단한 요약이 대략적으로 어떻게 작동하는지 설명합니다.

// This allocator implementation is designed to provide scalable performance
// for multi-threaded programs on multi-processor systems.  The following
// features are included for this purpose:
//
//   + Multiple arenas are used if there are multiple CPUs, which reduces lock
//     contention and cache sloshing.
//
//   + Cache line sharing between arenas is avoided for internal data
//     structures.
//
//   + Memory is managed in chunks and runs (chunks can be split into runs),
//     rather than as individual pages.  This provides a constant-time
//     mechanism for associating allocations with particular arenas.
//
// Allocation requests are rounded up to the nearest size class, and no record
// of the original request size is maintained.  Allocations are broken into
// categories according to size class.  Assuming runtime defaults, 4 kB pages
// and a 16 byte quantum on a 32-bit system, the size classes in each category
// are as follows:
//
//   |=====================================|
//   | Category | Subcategory    |    Size |
//   |=====================================|
//   | Small    | Tiny           |       4 |
//   |          |                |       8 |
//   |          |----------------+---------|
//   |          | Quantum-spaced |      16 |
//   |          |                |      32 |
//   |          |                |      48 |
//   |          |                |     ... |
//   |          |                |     480 |
//   |          |                |     496 |
//   |          |                |     512 |
//   |          |----------------+---------|
//   |          | Sub-page       |    1 kB |
//   |          |                |    2 kB |
//   |=====================================|
//   | Large                     |    4 kB |
//   |                           |    8 kB |
//   |                           |   12 kB |
//   |                           |     ... |
//   |                           | 1012 kB |
//   |                           | 1016 kB |
//   |                           | 1020 kB |
//   |=====================================|
//   | Huge                      |    1 MB |
//   |                           |    2 MB |
//   |                           |    3 MB |
//   |                           |     ... |
//   |=====================================|
//
// NOTE: Due to Mozilla bug 691003, we cannot reserve less than one word for an
// allocation on Linux or Mac.  So on 32-bit *nix, the smallest bucket size is
// 4 bytes, and on 64-bit, the smallest bucket size is 8 bytes.
//
// A different mechanism is used for each category:
//
//   Small : Each size class is segregated into its own set of runs.  Each run
//           maintains a bitmap of which regions are free/allocated.
//
//   Large : Each allocation is backed by a dedicated run.  Metadata are stored
//           in the associated arena chunk header maps.
//
//   Huge : Each allocation is backed by a dedicated contiguous set of chunks.
//          Metadata are stored in a separate red-black tree.
//
// *****************************************************************************

그러나 더 심층적 인 알고리즘 분석이 없습니다.


jemalloc이 mozilla에 가져온 이점에 대해서는 http://blog.pavlov.net/2008/03/11/firefox-3-memory-usage/에 따라 (또한 mozilla + jemalloc에 ​​대한 첫 번째 Google 결과) :

[...] jemalloc이 장기간 실행 한 후 가장 적은 양의 단편화를 제공한다는 결론을 내 렸습니다 . [...] Windows Vista에서 자동화 된 테스트에서 jemalloc을 켰을 때 메모리 사용량이 22 % 감소했습니다 .


Aerospike implemented jemalloc back in a private branch in 2013. In 2014, it was incorporated into Aerospike 3.3. Psi Mankoski just wrote about Aerospike's implementation, plus when and how to effectively use jemalloc, for High Scalability.

jemalloc really helped Aerospike take advantage of modern multithreaded, multi-CPU, multi-core computer architectures. There are also some very important debugging capabilities built in to jemalloc to manage arenas. The debugging allowed Psi to be able to tell, for instance, what was a true memory leak, versus what was the result of memory fragmentation. Psi also discusses how thread cache and per-thread allocation provided an overall performance (speed) improvement.

참고URL : https://stackoverflow.com/questions/1624726/how-does-jemalloc-work-what-are-the-benefits

반응형