constexpr size_t kMaxThreads = 8; // The max number of bytes that can be allocated by a thread. Note that each // allocator may have its own limitation on each size allocation. For example, // Scudo has a 256 MB limit for each size-class in the primary allocator. The // amount of memory allocated should not exceed the limit in each allocator.
constexpr size_t kMaxBytes = 1 << 24;
constexpr size_t kMaxLen = kMaxBytes; void* MemPool[kMaxThreads][kMaxLen];
void ThreadTask(int id, size_t allocSize) { // In the following, we will first allocate blocks with kMaxBytes of memory // and release all of them in random order. In the end, we will do another // round of allocations until it reaches 1/10 kMaxBytes.
// Total number of blocks const size_t maxCounts = kMaxBytes / allocSize; // The number of blocks in the end const size_t finalCounts = maxCounts / 10;
for (size_t i = 0; i < maxCounts; ++i) {
MemPool[id][i] = malloc(allocSize); if (MemPool[id][i] == 0) {
std::cout << "Allocation failure." "Please consider reducing the number of threads"
<< std::endl; exit(1);
}
dirtyMem(MemPool[id][i], allocSize);
}
// Each allocator may apply different strategies to manage the free blocks and // each strategy may have different impacts on future memory usage. For // example, managing free blocks in simple FIFO list may have its memory usage // highly correlated with the blocks releasing pattern. Therefore, release the // blocks in random order to observe the impact of free blocks handling. unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
std::shuffle(MemPool[id], MemPool[id] + maxCounts, std::default_random_engine(seed)); for (size_t i = 0; i < maxCounts; ++i) {
free(MemPool[id][i]);
MemPool[id][i] = nullptr;
}
for (size_t i = 0; i < finalCounts; ++i) {
MemPool[id][i] = malloc(allocSize);
dirtyMem(MemPool[id][i], allocSize);
}
}
void StressSizeClass(size_t numThreads, size_t allocSize) { // We would like to see the minimum memory usage under aggressive page // releasing.
mallopt(M_DECAY_TIME, 0);
std::thread* threads[kMaxThreads]; for (size_t i = 0; i < numThreads; ++i) threads[i] = new std::thread(ThreadTask, i, allocSize);
for (size_t i = 0; i < numThreads; ++i) {
threads[i]->join(); delete threads[i];
}
// Do an explicit purge to ensure we will be more likely to get the actual // in-use memory.
mallopt(M_PURGE_ALL, 0);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.