RFR: JDK-8301749: Tracking malloc pooled memory size
Thomas Stuefe
stuefe at openjdk.org
Wed Feb 8 07:56:58 UTC 2023
On Tue, 7 Feb 2023 15:00:14 GMT, Johan Sjölen <jsjolen at openjdk.org> wrote:
> This PR implements `os::malloc_info` by calling into glibc's `malloc_info` and provides a JCmd for asking the JVM to call `malloc_info` and print out the results. The user can make an informed decision regarding heap trimming by parsing the output of the JCmd. I wanted to avoid parsing the XML inside of the JVM , as this functionality may turn out to be "good enough". A future enhancement would be for the JVM to make this informed decision by parsing the output. Another may be to present this with other data, for example in NMT.
>
> @tstuefe, I think you'd be interested in this PR as it builds upon your `trim_native_heap` functionality.
>
> I'm using weak symbols (as per ELF) in order to compile this for both GLibc and Musl.
>
> The original bug description is this:
>
>>Memory not allocated via NMT and uncommitted memory contributes to a discrepancy between NMT and RSS.
> It can be hard to distinguish between these cases.
> If the VM can determine the amount of pooled memory by malloc it would help with both determining if a trim_native_memory is needed, or there are some allocations happening outside of NMT.
>>
>>It would be good if the VM can summarize the malloc pooled memory by using e.g. malloc_info(3).
>>
>>We can thus more precise account for RSS value.
@jdksjolen,
interesting. I considered malloc_info() too, but did not feel like parsing XML.
Generally, I would prefer if you keep it closer to what os::get_mallinf() is doing:
- only define and call that API for ifdef GLIBC
- resolve the traditional way via function pointers (see our mallinf()/mallinf2() wrappers)
- have the dcmd execute functions guarded with GLIBC, and an else branch saying its not glibc
This also needs tests. See existing test for trim_native_heap. I would also like a test for muslc to test the stub functionality (its missing from TrimLibcHeapTest.java, which I will add).
src/hotspot/os/linux/mallocInfoDcmd.cpp line 26:
> 24:
> 25: #include "precompiled.hpp"
> 26: #include "runtime/os.inline.hpp"
why this? why not os_linux.hpp?
src/hotspot/os/linux/mallocInfoDcmd.cpp line 28:
> 26: #include "runtime/os.inline.hpp"
> 27: #include "mallocInfoDcmd.hpp"
> 28: #include "utilities/debug.hpp"
What do you use from debug.hpp?
src/hotspot/os/linux/mallocInfoDcmd.cpp line 38:
> 36: char* buf;
> 37: size_t size;
> 38: ALLOW_C_FUNCTION(::open_memstream, FILE* stream = ::open_memstream(&buf, &size);)
I wondered how open_memstream communicates buffer growth (which may come with re-location). Then I realized that it just modifies the buffer start address the caller gives it in-place. What a weird API :)
You should handle error returns from open_memstream.
src/hotspot/os/linux/mallocInfoDcmd.cpp line 39:
> 37: size_t size;
> 38: ALLOW_C_FUNCTION(::open_memstream, FILE* stream = ::open_memstream(&buf, &size);)
> 39: if (!os::Linux::malloc_info(stream)) {
Style nit, can you change this to `if (os::Linux::malloc_info(stream) == 0)` ? Using `!` it reads like the failure branch.
src/hotspot/os/linux/mallocInfoDcmd.hpp line 36:
> 34: MallocInfoDcmd(outputStream* output, bool heap) : DCmd(output, heap) {}
> 35: static const char* name() {
> 36: return "System.malloc_info";
Nit, since the other one is called trim_native_heap, why not "native_heap_info"?
src/hotspot/os/linux/os_linux.cpp line 118:
> 116:
> 117: // Forward (re-)declare malloc_info in order to support Alpine Linux.
> 118: int __attribute__((weak)) malloc_info(int options, FILE *stream);
Not needed if you do it like os::get_mallinfo() and dlsym the API as proposed.
src/hotspot/os/linux/os_linux.cpp line 227:
> 225: return ::malloc_info(0, stream);
> 226: }
> 227: return 0;
return -1.
You aim to mimic the malloc_info() API at os:: level, so you should return -1 in case malloc_info failed, including failure do to resolving issues.
src/hotspot/os/linux/os_linux.hpp line 199:
> 197: // otherwise does nothing and returns 0.
> 198: static int malloc_info(FILE* stream);
> 199:
Could you put this at the end of the file, alongside os::get_mallinfo(), and within its ifdef GLIBC boundaries?
-------------
Changes requested by stuefe (Reviewer).
PR: https://git.openjdk.org/jdk/pull/12455
More information about the hotspot-runtime-dev
mailing list