diff --git a/benchmarks/malloc_rss_benchmark.cpp b/benchmarks/malloc_rss_benchmark.cpp
new file mode 100644
index 0000000..58f61d9
--- /dev/null
+++ b/benchmarks/malloc_rss_benchmark.cpp
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <malloc.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <algorithm>
+#include <chrono>
+#include <iostream>
+#include <memory>
+#include <random>
+#include <thread>
+#include <vector>
+
+#include <android-base/strings.h>
+#if defined(__BIONIC__)
+#include <malloc.h>
+#include <meminfo/procmeminfo.h>
+#include <procinfo/process_map.h>
+#endif
+
+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 dirtyMem(void* ptr, size_t bytes) {
+  memset(ptr, 1U, bytes);
+}
+
+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, 0);
+
+  android::meminfo::ProcMemInfo proc_mem(getpid());
+  const std::vector<android::meminfo::Vma>& maps = proc_mem.MapsWithoutUsageStats();
+  uint64_t rss_bytes = 0;
+  uint64_t vss_bytes = 0;
+
+  for (auto& vma : maps) {
+    if (vma.name == "[anon:libc_malloc]" || android::base::StartsWith(vma.name, "[anon:scudo:") ||
+        android::base::StartsWith(vma.name, "[anon:GWP-ASan")) {
+      android::meminfo::Vma update_vma(vma);
+      if (!proc_mem.FillInVmaStats(update_vma)) {
+        std::cout << "Failed to parse VMA" << std::endl;
+        exit(1);
+      }
+      rss_bytes += update_vma.usage.rss;
+      vss_bytes += update_vma.usage.vss;
+    }
+  }
+
+  std::cout << "RSS: " << rss_bytes / (1024.0 * 1024.0) << " MB" << std::endl;
+  std::cout << "VSS: " << vss_bytes / (1024.0 * 1024.0) << " MB" << std::endl;
+
+  for (size_t i = 0; i < numThreads; ++i) {
+    for (size_t j = 0; j < kMaxLen; ++j) free(MemPool[i][j]);
+  }
+}
+
+int main(int argc, char* argv[]) {
+  if (argc != 3) {
+    std::cerr << "usage: " << argv[0] << " $NUM_THREADS $ALLOC_SIZE" << std::endl;
+    return 1;
+  }
+
+  size_t numThreads = atoi(argv[1]);
+  size_t allocSize = atoi(argv[2]);
+
+  if (numThreads == 0 || allocSize == 0) {
+    std::cerr << "Please provide valid $NUM_THREADS and $ALLOC_SIZE" << std::endl;
+    return 1;
+  }
+
+  if (numThreads > kMaxThreads) {
+    std::cerr << "The max number of threads is " << kMaxThreads << std::endl;
+    return 1;
+  }
+
+  StressSizeClass(numThreads, allocSize);
+
+  return 0;
+}
