RFR: 8292989: Avoid dynamic memory in AsyncLogWriter

Xin Liu xliu at openjdk.org
Fri Sep 2 08:23:43 UTC 2022


On Wed, 31 Aug 2022 13:51:22 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 81:
> 
>> 79: const LogDecorations& AsyncLogWriter::None = LogDecorations(LogLevel::Warning, LogTagSetMapping<LogTag::__NO_TAG>::tagset(),
>> 80:                                       LogDecorators::None);
>> 81: // Note: there is an initializer order issue here. C++ cannot guarantee that 'None' is initialized before Token!
> 
> Can we avoid initializing these like this then? What happens if our expectations are not fulfilled some day in the future? I've been bit by bugs caused by this before, not very fun. Is there a reason they can't be initialized in AsyncLogWriter::initialize() for example?
> 
> Context for the curious:
> 
> https://en.cppreference.com/w/cpp/language/initialization
> 
> https://isocpp.org/wiki/faq/ctors#static-init-order
> 
> To be pedantic: I believe that None is guaranteed to be initialized before Token, but the LogTagSet which None is assigned to is not guaranteed to be initialized (because they're part of two different compilation units).

Sorry, this comment was misleading. I left it as a reminder. I mean c++ can't guarantee to initialize None and Token before `LogDecorators::None` is initialized. Like you said, LogDecorators::None is defined in another compilation unit. 

The reason it's right because `LogDecorators::None` is expected to be zero anyway. It's in bss section. That's why I feel it's tricky. I will change this part!

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

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


More information about the hotspot-runtime-dev mailing list