Add new mallopt M_LOG_STATS.
This new mallopt cause statistics of the allocator to be printed in
the log.
Add a stats print for jemalloc.
This is designed to be used as part of a dumpsys meminfo --XXXX
option so that it's easier to get information about apps that
have an unusual memory footprint.
Test: Unit tests pass.
Test: Ran on a device using jemalloc and verified log data.
Test: Ran on a device using scudo and verified log data.
Change-Id: I6fa44ce619c064b2596fbbb478c231994af94f4c
diff --git a/libc/bionic/jemalloc_wrapper.cpp b/libc/bionic/jemalloc_wrapper.cpp
index ce3f314..a2bb1db 100644
--- a/libc/bionic/jemalloc_wrapper.cpp
+++ b/libc/bionic/jemalloc_wrapper.cpp
@@ -19,10 +19,20 @@
#include <sys/param.h>
#include <unistd.h>
+#include <async_safe/log.h>
#include <private/MallocXmlElem.h>
#include "jemalloc.h"
+__BEGIN_DECLS
+
+size_t je_mallinfo_narenas();
+size_t je_mallinfo_nbins();
+struct mallinfo je_mallinfo_arena_info(size_t);
+struct mallinfo je_mallinfo_bin_info(size_t, size_t);
+
+__END_DECLS
+
void* je_pvalloc(size_t bytes) {
size_t pagesize = getpagesize();
size_t size = __BIONIC_ALIGN(bytes, pagesize);
@@ -121,19 +131,36 @@
return 0;
}
return 1;
+ } else if (param == M_LOG_STATS) {
+ for (size_t i = 0; i < je_mallinfo_narenas(); i++) {
+ struct mallinfo mi = je_mallinfo_arena_info(i);
+ if (mi.hblkhd != 0) {
+ async_safe_format_log(ANDROID_LOG_INFO, "jemalloc",
+ "Arena %zu: large bytes %zu huge bytes %zu bin bytes %zu", i,
+ mi.ordblks, mi.uordblks, mi.fsmblks);
+
+ for (size_t j = 0; j < je_mallinfo_nbins(); j++) {
+ struct mallinfo mi = je_mallinfo_bin_info(i, j);
+ if (mi.ordblks != 0) {
+ size_t total_allocs = 1;
+ if (mi.uordblks > mi.fordblks) {
+ total_allocs = mi.uordblks - mi.fordblks;
+ }
+ size_t bin_size = mi.ordblks / total_allocs;
+ async_safe_format_log(
+ ANDROID_LOG_INFO, "jemalloc",
+ " Bin %zu (%zu bytes): allocated bytes %zu nmalloc %zu ndalloc %zu", j, bin_size,
+ mi.ordblks, mi.uordblks, mi.fordblks);
+ }
+ }
+ }
+ }
+ return 1;
}
+
return 0;
}
-__BEGIN_DECLS
-
-size_t je_mallinfo_narenas();
-size_t je_mallinfo_nbins();
-struct mallinfo je_mallinfo_arena_info(size_t);
-struct mallinfo je_mallinfo_bin_info(size_t, size_t);
-
-__END_DECLS
-
int je_malloc_info(int options, FILE* fp) {
if (options != 0) {
errno = EINVAL;