RFR: 8292989: Avoid dynamic memory in AsyncLogWriter

Xin Liu xliu at openjdk.org
Wed Aug 31 18:10:08 UTC 2022


On Wed, 31 Aug 2022 14:01:53 GMT, Johan Sjölén <duke at openjdk.org> wrote:

>> Current implementation of AsyncLogWriter uses dynamic memory. There are 2 sources. 
>> 
>> 1. Overhead of pointer-based linked-list. 
>> 2. strdup of message contents
>> 
>> This implementation has impact on glibc/malloc. If allocation of logsites interleave with other allocation, it's hard to clean up all glibc arenas. This worsens fragmentation issue.
>> 
>> In this PR, we replace linked-list with `2 pre-allocated raw buffers`. AsyncLogWriter appends payload AsyncLogMessage to the serving buffer and avoids all dynamic allocation. Please note this effort won't eliminate mutex lock. We use ping-pong buffers to guarantee AsyncLogWriter is still non-blocking. A buffer serves as a FIFO queue like before. 
>> 
>> In addition, AsyncLogWriter doesn't enqueue meta messages anymore when it needs to report the number of discarded messages. This is archived using a temporary hashtable called `snapshot`. It copies the working hashtable with the protection of lock and reset it. After writing all regular messages, AsyncLogWriter writes meta messages from snapshot.
>
> src/hotspot/share/logging/logAsyncWriter.cpp line 125:
> 
>> 123:   size_t size = align_up(AsyncLogBufferSize / 2, page_size);
>> 124: 
>> 125:   char* buf0 = static_cast<char* >(os::malloc(size, mtLogging));
> 
> Is there a particular reason that AsyncLogWriter allocates and handles the resources intended for `Buffer` instead of `Buffer` doing it itself in its ctr and dtr?

I have no idea how to handle the error that malloc returns NULL in ctor. Maybe I am paranoid. glibc/malloc rarely fails because it maps but not commit a memory segment.  We also define the constraint of AsyncLogBufferSize in globals.hpp.

-------------

PR: https://git.openjdk.org/jdk/pull/10092


More information about the hotspot-runtime-dev mailing list