google / google/tcmalloc

Any appetite for upstreaming ability to use a custom allocator wrapping TCMalloc?

Open
#98 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
5.3k
Forks
570
Avg merge
23h 43m
Merged PRs (30d)
172

Description

I'm wondering if there's any appetite for upstreaming some changes to make it possible to utilize TCMalloc at the same time as another allocator. This may seem weird so let me try to explain. At Cloudflare workers, we let jobs take up to 128MB. Currently this limit is "weakly" enforced in that we're unable to accurately track native heap allocations. Basically it requires us to manually annotate substantial heap allocations to let V8 know the resource has been allocated & this misses many small allocations that are otherwise made lower in the stack.

So the design I'm exploring is to have 2 allocators - when we're allocating on behalf of a customer job, we'd use a custom allocator that allocates out of a fixed size arena allocated up-front at the start of the job. If there's no free space then I could continue allocating via TCMalloc & just mark that request as "misbehaving" for later graceful termination if necessary. When we're not allocating for a request (or the code explicitly switches to using the "system" allocation space), I want to defer to TCMalloc.

This would look either like:
* Supporting a mode where TCMalloc can be built without hooking into the global allocators. The internal TCMalloc allocation/free functions would be made visible in `malloc_extension.h`. Then I install my own allocators that make these kinds of policy decisions.
* Supporting a mode where I can register/unregister hooks with TCMalloc that can optionally handle the malloc/free or defer to TCMalloc. I've looked at the old gperftools APIs & they don't seem suitable for this purpose but I know you've mentioned the existence of APIs in the unreleased internal bits but I don't know if they allow for such a use-case.

Does either approach seem appealing? Are there other, better ways of accomplishing this? Are none of these things that would be acceptable upstream? I'm fine forking if such a thing is totally in conflict but obviously upstreaming small enabling work would be most convenient.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.