wang-jiahua commented on PR #10640:
URL: https://github.com/apache/rocketmq/pull/10640#issuecomment-5056306566

   Follow-up on the reusable-buffer memory bound — including a correction to my 
earlier thread-count characterization.
   
   ### Correction: which threads call `checkMessageAndReturnSize`
   
   In my previous comment I described this method as being called only by "the 
single `ReputMessageService` … not per connection/producer, small and bounded". 
That is imprecise — the calling-thread count depends on the dispatch mode:
   
   | mode | switch (default) | threads that call it | steady-state count |
   |---|---|---|---|
   | default dispatch | `enableBuildConsumeQueueConcurrently=false` (default) | 
single `ReputMessageService` | 1 |
   | concurrent dispatch | `=true` | the `MainBatchDispatchRequestService` 
thread pool | = `batchDispatchRequestThreadPoolNums` (default 16, can be 
raised) |
   
   (Startup recovery and the HA service also call it, but recovery threads are 
transient and release their `ThreadLocal` buffer on exit.)
   
   So under concurrent dispatch the buffer is retained per pool thread, and the 
worst-case retained memory is:
   
   ```
   min(largest message actually seen, maxCheckMessageReuseBufferSize) × number 
of dispatch threads
   ```
   
   The buffer is grow-only, so it only grows to the largest ≤ cap message 
actually encountered — with typical KB-sized messages the retention is 
negligible regardless of thread count; it only approaches `cap × threads` when 
messages near the cap are common.
   
   ### Change: lowered the default cap to 1 MiB
   
   To be safe-by-default under concurrent dispatch (and mindful of tight 
production memory), I lowered the default `maxCheckMessageReuseBufferSize` from 
`4 MiB + 64 KiB` to **1 MiB**. It still covers the vast majority of messages, 
but bounds worst-case per-thread retention to 1 MiB — e.g. concurrent dispatch 
with the default pool of 16 threads is now ≤ 16 MiB instead of ≤ ~64 MiB. 
Messages in the 1–4 MiB range now take the transient path (no reuse benefit, 
but no regression versus the current code); operators with predominantly larger 
messages can raise the knob.
   
   Updated micro-benchmark under the 1 MiB default (`ThreadMXBean`, warmed to 
steady state):
   
   | distribution | old B/op | new B/op | saved |
   |---|---:|---:|---:|
   | uniform 2 KB | 2,320 | 0 | 100% |
   | mixed small (512 B / 2 KB / 8 KB) | 3,728 | 0 | 100% |
   | 99% 2 KB + 1% 5 MB (> cap) | 54,726 | 52,429 | 4.2% |
   | uniform 2 MB (> cap) | 2,097,168 | 2,097,168 | 0% (transient, no 
regression) |
   
   Pushed as a follow-up commit.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to