-
Notifications
You must be signed in to change notification settings - Fork 5.8k
8292989: Avoid dynamic memory in AsyncLogWriter #10092
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
1. replace iterator with C++ lambda and don't enqueue counters. 2. reserve space for flushing token, so push_back(token) is always successful.
👋 Welcome back xliu! A progress list of the required criteria for merging this PR into |
Webrevs
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for your PR. A few comments from me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi Xin,
This is good, and goes into the right direction.
General remark:
Since you allocate the buffers up-front, you really don't have to handle allocation failures. Just consider:
- In the vast majority of cases the user will not modify
AsyncLogBufferSize
, and if we fail to malloc 4 MB at VM start we have a much larger problem. - And if the user specifies
AsyncLogBufferSize
, but with such an outrageously large buffer that it fails to allocate, it is also better to fail. Because the user had a good reason to specify-Xlog:async
, and you don't want to quietly fall back to synchronous logging. Also, maybe the user made just a stupid argument mistake, then again, you don't want to quielty swallow that error.
If you remove the allocation failure handling, you can simplify quite a bit, e.g. also get rid of Buffer::is_valid()
, AsyncLogWriter::Buffer::~Buffer()
, etc.
More remarks inline.
Cheers, Thomas
This saves a pointer(8-byte on LP64 machines) for each message. Resume default size of buffer to 2M because -Xlog:all=debug -Xlog:async doesn't drop any message.
MSVC reports logAsyncWriter.cpp(62): warning C4267: 'initializing': conversion from 'size_t' to 'int', possible loss of data
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi Xin,
getting closer. Remarks inline.
Cheers, Thomas
Also add a unit test for AsyncLogWriter::Buffer.
MSVC doesn't use C99.
This patch changed the behehavior of Buffer. Enqueuing a null message is not allowed and it will trigger an assertion in debug build.
it's still a compiler-time constant like TOKEN_SIZE. put the headroom logic in Buffer::push_back().
hi, @tstuefe, Thank you for reviewing this patch! I addressed most of the requests. I haven't integrated the 'len' hint yet. It's not I don't intend to. On the contrary, I found that reducing the size of 'Message' is very useful to avoid buffer overflow. I took you advice and saved the explicit c-str pointer. Another observation is that almost all Can we leave
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me. Thanks for taking my suggestions. I'm fine with delaying further refinements to future RFEs.
Thanks, Thomas
@navyxliu This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be:
You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 267 new commits pushed to the
As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details. ➡️ To integrate this PR with the above commit message to the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for your efforts, this LGTM now.
@jdksjolen (no known github.com user name / role)
I've forgotten to associate my OpenJDK account with my Github account, so my approval counts for nothing at the moment :-(.
IIRC, in hotspot we need two reviews, one Reviewer, the other at least Contributor. Maybe one of your team should propose you as Contributor (@coleenp?), then your reviews count too. I think you have the required number of patches already. |
I've heard Reviewer + Author is fine, but I'll get a Contributor to look at this. I think I have the required number of patches, but not all of them are non-trivial so I'm waiting a bit to remove any doubt about the outcome of a vote. |
Maybe you are right and Author is sufficient for the second vote. Whenever I look for the relevant wiki page I cannot find it :) Up to @navyxliu of course, but since we are not stormed by willing reviewers, I'd just push. |
Just integrating sounds good to me. |
/integrate |
Going to push as commit bf79f99.
Your commit was automatically rebased without conflicts. |
Thanks @tstuefe and @jdksjolen for reviewing this! |
Current implementation of AsyncLogWriter uses dynamic memory. There are 2 sources.
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.Progress
Issue
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk pull/10092/head:pull/10092
$ git checkout pull/10092
Update a local copy of the PR:
$ git checkout pull/10092
$ git pull https://git.openjdk.org/jdk pull/10092/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 10092
View PR using the GUI difftool:
$ git pr show -t 10092
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/10092.diff