Excessive VM usage with jemalloc
Abhishek Singh
abhishek at abhishek-singh.com
Sun Apr 28 22:51:34 PDT 2013
sending the patch inline as the mail system does not see to like
attachments.
diff -rupN jemalloc-3.3.1/include/jemalloc/internal/chunk.h
jemalloc-3.3.1_changed/include/jemalloc/internal/chunk.h
--- jemalloc-3.3.1/include/jemalloc/internal/chunk.h 2013-03-07
01:34:18.000000000 +0530
+++ jemalloc-3.3.1_changed/include/jemalloc/internal/chunk.h 2013-04-26
19:40:12.000000000 +0530
@@ -45,8 +45,8 @@ extern size_t arena_maxclass; /* Max si
void *chunk_alloc(size_t size, size_t alignment, bool base, bool *zero,
dss_prec_t dss_prec);
-void chunk_unmap(void *chunk, size_t size);
-void chunk_dealloc(void *chunk, size_t size, bool unmap);
+void chunk_unmap(void *chunk, size_t size, bool force_unmap);
+void chunk_dealloc(void *chunk, size_t size, bool unmap, bool
force_unmap);
bool chunk_boot(void);
void chunk_prefork(void);
void chunk_postfork_parent(void);
diff -rupN jemalloc-3.3.1/include/jemalloc/internal/chunk_mmap.h
jemalloc-3.3.1_changed/include/jemalloc/internal/chunk_mmap.h
--- jemalloc-3.3.1/include/jemalloc/internal/chunk_mmap.h 2013-03-07
01:34:18.000000000 +0530
+++ jemalloc-3.3.1_changed/include/jemalloc/internal/chunk_mmap.h
2013-04-26 19:34:36.000000000 +0530
@@ -12,7 +12,7 @@
bool pages_purge(void *addr, size_t length);
void *chunk_alloc_mmap(size_t size, size_t alignment, bool *zero);
-bool chunk_dealloc_mmap(void *chunk, size_t size);
+bool chunk_dealloc_mmap(void *chunk, size_t size, bool force_unmap);
#endif /* JEMALLOC_H_EXTERNS */
/******************************************************************************/
/******************************************************************************/
Binary files jemalloc-3.3.1/lib/libjemalloc.so.2 and
jemalloc-3.3.1_changed/lib/libjemalloc.so.2 differ
diff -rupN jemalloc-3.3.1/src/arena.c jemalloc-3.3.1_changed/src/arena.c
--- jemalloc-3.3.1/src/arena.c 2013-03-07 01:34:18.000000000 +0530
+++ jemalloc-3.3.1_changed/src/arena.c 2013-04-26 19:40:33.000000000 +0530
@@ -617,7 +617,7 @@ arena_chunk_dealloc(arena_t *arena, aren
arena->spare = chunk;
malloc_mutex_unlock(&arena->lock);
- chunk_dealloc((void *)spare, chunksize, true);
+ chunk_dealloc((void *)spare, chunksize, true, false);
malloc_mutex_lock(&arena->lock);
if (config_stats)
arena->stats.mapped -= chunksize;
diff -rupN jemalloc-3.3.1/src/chunk.c jemalloc-3.3.1_changed/src/chunk.c
--- jemalloc-3.3.1/src/chunk.c 2013-03-07 01:34:18.000000000 +0530
+++ jemalloc-3.3.1_changed/src/chunk.c 2013-04-26 19:39:33.000000000 +0530
@@ -104,7 +104,7 @@ chunk_recycle(extent_tree_t *chunks_szad
malloc_mutex_unlock(&chunks_mtx);
node = base_node_alloc();
if (node == NULL) {
- chunk_dealloc(ret, size, true);
+ chunk_dealloc(ret, size, true, false);
return (NULL);
}
malloc_mutex_lock(&chunks_mtx);
@@ -181,7 +181,7 @@ label_return:
if (ret != NULL) {
if (config_ivsalloc && base == false) {
if (rtree_set(chunks_rtree, (uintptr_t)ret, ret)) {
- chunk_dealloc(ret, size, true);
+ chunk_dealloc(ret, size, true, false);
return (NULL);
}
}
@@ -288,7 +288,7 @@ chunk_record(extent_tree_t *chunks_szad,
}
void
-chunk_unmap(void *chunk, size_t size)
+chunk_unmap(void *chunk, size_t size, bool force_unmap)
{
assert(chunk != NULL);
assert(CHUNK_ADDR2BASE(chunk) == chunk);
@@ -297,12 +297,12 @@ chunk_unmap(void *chunk, size_t size)
if (config_dss && chunk_in_dss(chunk))
chunk_record(&chunks_szad_dss, &chunks_ad_dss, chunk, size);
- else if (chunk_dealloc_mmap(chunk, size))
+ else if (chunk_dealloc_mmap(chunk, size, force_unmap))
chunk_record(&chunks_szad_mmap, &chunks_ad_mmap, chunk,
size);
}
void
-chunk_dealloc(void *chunk, size_t size, bool unmap)
+chunk_dealloc(void *chunk, size_t size, bool unmap, bool force_unmap)
{
assert(chunk != NULL);
@@ -320,7 +320,7 @@ chunk_dealloc(void *chunk, size_t size,
}
if (unmap)
- chunk_unmap(chunk, size);
+ chunk_unmap(chunk, size, force_unmap);
}
bool
diff -rupN jemalloc-3.3.1/src/chunk_dss.c
jemalloc-3.3.1_changed/src/chunk_dss.c
--- jemalloc-3.3.1/src/chunk_dss.c 2013-03-07 01:34:18.000000000 +0530
+++ jemalloc-3.3.1_changed/src/chunk_dss.c 2013-04-26
19:38:11.000000000 +0530
@@ -123,7 +123,7 @@ chunk_alloc_dss(size_t size, size_t alig
dss_max = dss_next;
malloc_mutex_unlock(&dss_mtx);
if (cpad_size != 0)
- chunk_unmap(cpad, cpad_size);
+ chunk_unmap(cpad, cpad_size, false);
if (*zero) {
VALGRIND_MAKE_MEM_UNDEFINED(ret,
size);
memset(ret, 0, size);
diff -rupN jemalloc-3.3.1/src/chunk_mmap.c
jemalloc-3.3.1_changed/src/chunk_mmap.c
--- jemalloc-3.3.1/src/chunk_mmap.c 2013-03-07 01:34:18.000000000 +0530
+++ jemalloc-3.3.1_changed/src/chunk_mmap.c 2013-04-26
19:48:15.000000000 +0530
@@ -200,11 +200,10 @@ chunk_alloc_mmap(size_t size, size_t ali
}
bool
-chunk_dealloc_mmap(void *chunk, size_t size)
+chunk_dealloc_mmap(void *chunk, size_t size, bool force_unmap)
{
-
- if (config_munmap)
+ if (config_munmap || force_unmap)
pages_unmap(chunk, size);
- return (config_munmap == false);
+ return (config_munmap == false) && (force_unmap == false);
}
diff -rupN jemalloc-3.3.1/src/huge.c jemalloc-3.3.1_changed/src/huge.c
--- jemalloc-3.3.1/src/huge.c 2013-03-07 01:34:18.000000000 +0530
+++ jemalloc-3.3.1_changed/src/huge.c 2013-04-26 19:49:39.000000000 +0530
@@ -175,7 +175,7 @@ huge_ralloc(void *ptr, size_t oldsize, s
if (opt_abort)
abort();
memcpy(ret, ptr, copysize);
- chunk_dealloc_mmap(ptr, oldsize);
+ chunk_dealloc_mmap(ptr, oldsize, true);
}
} else
#endif
@@ -211,7 +211,7 @@ huge_dalloc(void *ptr, bool unmap)
if (unmap && config_fill && config_dss && opt_junk)
memset(node->addr, 0x5a, node->size);
- chunk_dealloc(node->addr, node->size, unmap);
+ chunk_dealloc(node->addr, node->size, unmap, unmap);
base_node_dealloc(node);
}
On Mon, Apr 29, 2013 at 9:33 AM, Abhishek Singh <abhishek at abhishek-singh.com
> wrote:
> Hi
>
> We are trying to replace glibc malloc with jemalloc because we have
> several concurrent allocations and in all our benchmarks jemalloc is
> consistently better than glibc malloc and many others.
>
> Our setups start typically with 96 GB of RAM and up. We have observed that
> using jemalloc the virtual memory usage of our process rises up to around
> 75GB. While the resident memory stays low and it is not a problem as such,
> when we try to fork a process from within here, it fails as the kernel
> assumes there is not enough memory to copy the VM space. Perhaps a vfork
> would be better but we can't use that for now.
>
> So we have made some modifications to jemalloc so that all huge memory
> allocations are forced to unmap their memory on freeing up. Non huge memory
> allocations and freeing up remain the same. This seems to help us. I have
> attached the patch here which is against jemalloc-3.3.1. Please review and
> suggest if there is a better way to handle this.
>
> --
> Regards
> Abhishek
>
--
Regards
Abhishek Kumar Singh
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://jemalloc.net/mailman/jemalloc-discuss/attachments/20130429/1be08daa/attachment.html>
More information about the jemalloc-discuss
mailing list