[ 
https://issues.apache.org/jira/browse/IGNITE-28980?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18105259#comment-18105259
 ] 

Evgeny Stanilovsky commented on IGNITE-28980:
---------------------------------------------

[~mroeppis] thank you, fill some comments, plz check them 

> BinaryMemoryAllocator$ThreadLocalAllocator$Chunk does not reset maxMsgSize 
> after shrink check
> ---------------------------------------------------------------------------------------------
>
>                 Key: IGNITE-28980
>                 URL: https://issues.apache.org/jira/browse/IGNITE-28980
>             Project: Ignite
>          Issue Type: Bug
>          Components: general
>    Affects Versions: 2.18
>         Environment: * Apache Ignite 2.18.0
> * {{BinaryMemoryAllocator$ThreadLocalAllocator$Chunk}}
> * Java 25.0.3+9
> * Linux 6.8.0-100-generic amd64
>            Reporter: Mathias Roeppischer
>            Assignee: Mathias Roeppischer
>            Priority: Major
>             Fix For: 2.19
>
>          Time Spent: 0.5h
>  Remaining Estimate: 0h
>
> {{BinaryMemoryAllocator$ThreadLocalAllocator$Chunk}} keeps track of the 
> maximum message size detected between checks in {{maxMsgSize}}.
> The value is updated as follows:
> {code:java}
> if (maxMsgSize > this.maxMsgSize)
>     this.maxMsgSize = maxMsgSize;
> {code}
> The shrink logic periodically checks this value based on {{CHECK_FREQ}}:
> {code:java}
> if (CommonUtils.nanosToMillis(nowNanos - lastCheckNanos) >= CHECK_FREQ) {
>     int halfSize = data.length >> 1;
>     if (this.maxMsgSize < halfSize)
>         this.data = new byte[halfSize];
>     lastCheckNanos = nowNanos;
> }
> {code}
> However, {{this.maxMsgSize}} is never reset after the check.
> As a result, the value effectively represents the maximum message size seen 
> during the entire lifetime of the {{Chunk}}, rather than the maximum message 
> size detected between checks as documented.
> h3. Impact
> A single large serialization can permanently prevent the chunk from shrinking 
> again.
> For example, if a chunk grows to 128 MB due to a large message and 
> {{maxMsgSize}} reaches 100 MB, subsequent small messages cannot lower 
> {{maxMsgSize}} below 100 MB. Consequently, the shrink condition
> {code:java}
> this.maxMsgSize < halfSize
> {code}
> may never become true, even if the chunk is subsequently used only for much 
> smaller messages.
> This can cause large byte arrays to remain retained by thread-local 
> allocators. In applications using thread pools, a number of worker threads 
> can therefore retain large buffers after processing occasional large 
> messages, resulting in unnecessarily high heap usage.
> h3. Expected behavior
> {{maxMsgSize}} should represent the maximum message size observed during the 
> current check interval.
> After the shrink check has been performed, the recorded maximum should be 
> reset so that the next interval starts with a fresh measurement.
> h3. Proposed fix
> Reset {{maxMsgSize}} after each {{CHECK_FREQ}} check:
> {code:java}
> if (CommonUtils.nanosToMillis(nowNanos - lastCheckNanos) >= CHECK_FREQ) {
>     int halfSize = data.length >> 1;
>     if (this.maxMsgSize < halfSize)
>         this.data = new byte[halfSize];
>     this.maxMsgSize = 0;
>     lastCheckNanos = nowNanos;
> }
> {code}
> This preserves the existing design of collecting the maximum message size 
> between checks while allowing the chunk to shrink when subsequent 
> serialization workloads are smaller.
> h3. Additional Information
> Discussion on the Ignite User Mailing list:
> https://lists.apache.org/thread/cr2rvdpyh1njn2wghvg1mq7gr66wgjls



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to