Aias00 opened a new issue, #7803:
URL: https://github.com/apache/shenyu/issues/7803
### Is there an existing issue for this?
- [x] I searched existing issues. #6610 and #7463 concern queue
rejection/offer behavior, but do not cover JVM committed heap versus maximum
heap headroom.
### Current Behavior
Starting a gateway with `-Xms256m -Xmx768m` can cause its shared wheel timer
to reject scheduled tasks even when several hundred MiB remain available below
`-Xmx`.
During a local Docker deployment, the gateway HTTP health endpoint was UP,
but the timer logged task rejection and gateway heartbeat registration did not
progress normally. Increasing the initial heap to 1 GiB made the scheduled work
and heartbeat registration work.
A standalone reproduction against the same built ShenYu classes produced:
```text
# -Xms256m -Xmx768m
committedMiB=256
freeCommittedMiB=156
headroomToXmxMiB=668
accepted=false
# -Xms1g -Xmx1536m
committedMiB=1024
freeCommittedMiB=970
headroomToXmxMiB=1482
accepted=true
```
This is a custom small-heap deployment, not a claim that the stock Docker
entrypoint's 2 GiB defaults fail.
### Expected Behavior
Task admission should account for genuinely available heap, including memory
that the JVM can commit up to `-Xmx`, or clearly validate/document a minimum
initial heap. An otherwise healthy gateway should not silently lose recurring
timer/heartbeat work because its initial committed heap is below a fixed queue
threshold.
### Steps To Reproduce
1. Build the current gateway distribution.
2. Run the following with `-Xms256m -Xmx768m` and the distribution's `lib/*`
on the classpath:
```java
import org.apache.shenyu.common.concurrent.MemorySafeLinkedBlockingQueue;
public class HeapAdmissionRepro {
public static void main(String[] args) {
Runtime runtime = Runtime.getRuntime();
long used = runtime.totalMemory() - runtime.freeMemory();
MemorySafeLinkedBlockingQueue<Runnable> queue =
new MemorySafeLinkedBlockingQueue<>(256 * 1024 * 1024);
System.out.println("committedMiB=" + runtime.totalMemory() / 1024 /
1024);
System.out.println("freeCommittedMiB=" + runtime.freeMemory() / 1024
/ 1024);
System.out.println("headroomToXmxMiB=" + (runtime.maxMemory() -
used) / 1024 / 1024);
System.out.println("accepted=" + queue.offer(() -> {}));
System.exit(0);
}
}
```
3. Observe `accepted=false` despite sufficient maximum-heap headroom. A
bootstrap using `HierarchicalWheelTimer` exhibits the timer rejection below.
4. Compare with a larger initial heap.
### Environment
- ShenYu: `2.7.2-SNAPSHOT`, master `04f7c2e8b7d282f14510157a9ab0bfaab538ecac`
- Local deployment: ARM64 Linux containers, Eclipse Temurin Java 17,
macOS/OrbStack host
- Standalone admission check: Java 17
### Debug logs
```text
WARN HierarchicalWheelTimer - Dropping the expired timer task because the
timer task queue has no remaining memory
java.util.concurrent.RejectedExecutionException: Queue capacity is full.
at
org.apache.shenyu.common.concurrent.ShenyuThreadPoolExecutor.execute(...)
at
org.apache.shenyu.common.timer.HierarchicalWheelTimer.addTimerTaskEntry(...)
```
### Code evidence
- [MemoryLimitCalculator.java, lines
56–58](https://github.com/apache/shenyu/blob/04f7c2e8b7d282f14510157a9ab0bfaab538ecac/shenyu-common/src/main/java/org/apache/shenyu/common/concurrent/MemoryLimitCalculator.java#L56-L58)
sets its available-memory value to `Runtime.freeMemory()`, which describes
unused **committed** heap.
- [MemorySafeLinkedBlockingQueue.java, lines
84–95](https://github.com/apache/shenyu/blob/04f7c2e8b7d282f14510157a9ab0bfaab538ecac/shenyu-common/src/main/java/org/apache/shenyu/common/concurrent/MemorySafeLinkedBlockingQueue.java#L84-L95)
gates admission on this value.
- [HierarchicalWheelTimer.java, lines
90–95](https://github.com/apache/shenyu/blob/04f7c2e8b7d282f14510157a9ab0bfaab538ecac/shenyu-common/src/main/java/org/apache/shenyu/common/timer/HierarchicalWheelTimer.java#L90-L95)
fixes the queue threshold at `THE_256_MB`.
Please cover `Xms < Xmx` in regression tests and review the admission
calculation and the timer's fixed threshold. A possible calculation to evaluate
is `maxMemory - (totalMemory - freeMemory)`; this issue does not prescribe it
without reviewing the intended memory protection policy.
--
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]