awslabs / awslabs/aws-eventstream-java

Defensive copies of payloads trigger G1 humongous allocations

Open
#6 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
5
Forks
6
PR merge metrics
No merged PRs in 30d

Description

# Message constructor and getPayload() make defensive copies of large payloads, causing G1 humongous allocations

## Describe the bug

`Message` makes two unconditional defensive copies of the payload byte array:

```java
// Message.java — constructor
this.payload = requireNonNull(payload, "payload").clone();

// Message.java — getter
public byte[] getPayload() {
return payload.clone();
}
```

On a dev machine (8 vCPUs, 18 GB heap) for payloads larger than ~8 MB (half of a 16 MB G1 region), each clone is a **G1 humongous allocation** and may directly trigger a GC cycle. Humongous allocations degrade the overall system performance.

## Possible Solution

Should `Message` class has no-copy constructor and payload getter using which will reduce unnecessary memory allocations?

## Additional details

There are more allocations, e.g. [array allocation during decoding](https://github.com/awslabs/aws-eventstream-java/blob/master/src/main/java/software/amazon/eventstream/Message.java#L98) or [underlying BAOS array resizing](https://github.com/awslabs/aws-eventstream-java/blob/master/src/main/java/software/amazon/eventstream/Message.java#L132). But these were not present on JFR recordings.

## Library version used

`aws-eventstream 1.0.1` (via `aws-sdk 2.41.24`)

## JDK version used

`21.0.10`

## Operating System and version

Linux

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.