This is an automated email from the ASF dual-hosted git repository.
lhotari pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pulsar.git
The following commit(s) were added to refs/heads/master by this push:
new 0bc9dcbca3f [improve][broker] Update netty allocator default chunk
size from 4MB to 8MB, and move internal JVM opts from PULSAR_EXTRA_OPTS to OPTS
(#25274)
0bc9dcbca3f is described below
commit 0bc9dcbca3fb2d1a43a6cda630e2e34fdec6b8cd
Author: zhou zhuohan <[email protected]>
AuthorDate: Mon Mar 9 19:41:52 2026 +0800
[improve][broker] Update netty allocator default chunk size from 4MB to
8MB, and move internal JVM opts from PULSAR_EXTRA_OPTS to OPTS (#25274)
---
bin/bookkeeper | 20 ++++++++++++
bin/function-localrunner | 29 ++++++++++++++---
bin/pulsar | 25 +++++++++++++++
bin/pulsar-admin-common.cmd | 24 +++++++++++++++
bin/pulsar-admin-common.sh | 24 +++++++++++++++
bin/pulsar-perf | 24 +++++++++++++++
conf/bkenv.sh | 3 +-
conf/pulsar_env.sh | 3 --
conf/pulsar_tools_env.sh | 3 +-
.../terraform-ansible/templates/pulsar_env.sh | 3 --
.../PulsarByteBufAllocatorDefaultTest.java | 36 ++++++++++++++++++++++
src/pulsar-io-gen.sh | 24 +++++++++++++++
.../integration/containers/PulsarContainer.java | 2 --
13 files changed, 203 insertions(+), 17 deletions(-)
diff --git a/bin/bookkeeper b/bin/bookkeeper
index b61123e3c85..6a0fee9101a 100755
--- a/bin/bookkeeper
+++ b/bin/bookkeeper
@@ -209,6 +209,26 @@ OPTS="-Djava.net.preferIPv4Stack=true $OPTS"
if [[ $JAVA_MAJOR_VERSION -ge 23 ]]; then
OPTS="--sun-misc-unsafe-memory-access=allow $OPTS"
fi
+# Netty tuning
+# These settings are primarily used to modify the Netty allocator
configuration,
+# improving memory utilization and reducing the frequency of requesting
off-heap memory from the OS
+#
+# Based on the netty source code, the allocator's default chunk size is
calculated as:
+# io.netty.allocator.pageSize (default: 8192) shifted left by
+# io.netty.allocator.maxOrder (default: 9 after Netty 4.1.76.Final version).
+# This equals 8192 * 2^9 = 4 MB:
+#
https://github.com/netty/netty/blob/4.1/buffer/src/main/java/io/netty/buffer/PooledByteBufAllocator.java#L105
+#
+# Allocations that are larger than chunk size are considered huge allocations
and don't use the pool:
+#
https://github.com/netty/netty/blob/4.1/buffer/src/main/java/io/netty/buffer/PoolArena.java#L141-L142
+#
+# Currently, Pulsar defaults to a maximum single message size of 5 MB.
+# Therefore, when frequently producing messages whose size exceeds the chunk
size,
+# Netty cannot utilize resources from the memory pool and must frequently
allocate native memory.
+# This can lead to increased physical memory fragmentation and higher
reclamation costs.
+# Thus, increasing io.netty.allocator.maxOrder to 10 to ensure that a single
message is larger
+# than chunk size (8MB) and can reuse Netty's memory pool.
+OPTS="-Dio.netty.leakDetection.level=disabled
-Dio.netty.recycler.maxCapacityPerThread=4096 -Dio.netty.allocator.maxOrder=10
$OPTS"
OPTS="$OPTS $BOOKIE_MEM $BOOKIE_GC $BOOKIE_GC_LOG $BOOKIE_EXTRA_OPTS"
diff --git a/bin/function-localrunner b/bin/function-localrunner
index 74def8fcd96..87f0a9a23b7 100755
--- a/bin/function-localrunner
+++ b/bin/function-localrunner
@@ -76,9 +76,6 @@ if [[ -z "$PULSAR_GC_LOG" ]]; then
fi
fi
-# Extra options to be passed to the jvm
-PULSAR_EXTRA_OPTS=${PULSAR_EXTRA_OPTS:-" -Dpulsar.allocator.exit_on_oom=true
-Dio.netty.recycler.maxCapacityPerThread=4096"}
-
if [ -z "$PULSAR_LOG_CONF" ]; then
PULSAR_LOG_CONF=$DEFAULT_LOG_CONF
fi
@@ -139,9 +136,31 @@ if [[ $JAVA_MAJOR_VERSION -ge 23 ]]; then
fi
OPTS="-cp $PULSAR_CLASSPATH $OPTS"
-
# we should exit on OOM for localrun especially when using ThreadRuntime
-PULSAR_EXTRA_OPTS="$PULSAR_EXTRA_OPTS -XX:+ExitOnOutOfMemoryError"
+# These two settings work together to ensure the Pulsar process exits
immediately and predictably
+# if it runs out of either Java heap memory or its internal off-heap memory,
+# as these are unrecoverable errors that require a process restart to clear
the faulty state and restore operation
+OPTS="-XX:+ExitOnOutOfMemoryError -Dpulsar.allocator.exit_on_oom=true $OPTS"
+# Netty tuning
+# These settings are primarily used to modify the Netty allocator
configuration,
+# improving memory utilization and reducing the frequency of requesting
off-heap memory from the OS
+#
+# Based on the netty source code, the allocator's default chunk size is
calculated as:
+# io.netty.allocator.pageSize (default: 8192) shifted left by
+# io.netty.allocator.maxOrder (default: 9 after Netty 4.1.76.Final version).
+# This equals 8192 * 2^9 = 4 MB:
+#
https://github.com/netty/netty/blob/4.1/buffer/src/main/java/io/netty/buffer/PooledByteBufAllocator.java#L105
+#
+# Allocations that are larger than chunk size are considered huge allocations
and don't use the pool:
+#
https://github.com/netty/netty/blob/4.1/buffer/src/main/java/io/netty/buffer/PoolArena.java#L141-L142
+#
+# Currently, Pulsar defaults to a maximum single message size of 5 MB.
+# Therefore, when frequently producing messages whose size exceeds the chunk
size,
+# Netty cannot utilize resources from the memory pool and must frequently
allocate native memory.
+# This can lead to increased physical memory fragmentation and higher
reclamation costs.
+# Thus, increasing io.netty.allocator.maxOrder to 10 to ensure that a single
message is larger
+# than chunk size (8MB) and can reuse Netty's memory pool.
+OPTS="-Dio.netty.recycler.maxCapacityPerThread=4096
-Dio.netty.allocator.maxOrder=10 $OPTS"
OPTS="$OPTS $PULSAR_EXTRA_OPTS $PULSAR_MEM $PULSAR_GC"
diff --git a/bin/pulsar b/bin/pulsar
index b879019eb18..24897c3d3db 100755
--- a/bin/pulsar
+++ b/bin/pulsar
@@ -300,10 +300,35 @@ OPTS="$OPTS --add-opens java.base/java.nio=ALL-UNNAMED
--add-opens java.base/jdk
OPTS="$OPTS --add-opens java.base/jdk.internal.platform=ALL-UNNAMED"
# Required by RocksDB java.lang.System::loadLibrary call
OPTS="$OPTS --enable-native-access=ALL-UNNAMED"
+# These two settings work together to ensure the Pulsar process exits
immediately and predictably
+# if it runs out of either Java heap memory or its internal off-heap memory,
+# as these are unrecoverable errors that require a process restart to clear
the faulty state and restore operation
+OPTS="-XX:+ExitOnOutOfMemoryError -Dpulsar.allocator.exit_on_oom=true $OPTS"
+# Netty tuning
+# These settings are primarily used to modify the Netty allocator
configuration,
+# improving memory utilization and reducing the frequency of requesting
off-heap memory from the OS
+#
+# Based on the netty source code, the allocator's default chunk size is
calculated as:
+# io.netty.allocator.pageSize (default: 8192) shifted left by
+# io.netty.allocator.maxOrder (default: 9 after Netty 4.1.76.Final version).
+# This equals 8192 * 2^9 = 4 MB:
+#
https://github.com/netty/netty/blob/4.1/buffer/src/main/java/io/netty/buffer/PooledByteBufAllocator.java#L105
+#
+# Allocations that are larger than chunk size are considered huge allocations
and don't use the pool:
+#
https://github.com/netty/netty/blob/4.1/buffer/src/main/java/io/netty/buffer/PoolArena.java#L141-L142
+#
+# Currently, Pulsar defaults to a maximum single message size of 5 MB.
+# Therefore, when frequently producing messages whose size exceeds the chunk
size,
+# Netty cannot utilize resources from the memory pool and must frequently
allocate native memory.
+# This can lead to increased physical memory fragmentation and higher
reclamation costs.
+# Thus, increasing io.netty.allocator.maxOrder to 10 to ensure that a single
message is larger
+# than chunk size (8MB) and can reuse Netty's memory pool.
+OPTS="-Dio.netty.recycler.maxCapacityPerThread=4096
-Dio.netty.allocator.maxOrder=10 $OPTS"
OPTS="-cp $PULSAR_CLASSPATH $OPTS"
if [ $COMMAND == "bookie" ]; then
+ OPTS="-Dio.netty.leakDetection.level=disabled $OPTS"
# Pass BOOKIE_EXTRA_OPTS option defined in bkenv.sh
OPTS="$OPTS $BOOKIE_MEM $BOOKIE_GC $BOOKIE_GC_LOG $BOOKIE_EXTRA_OPTS"
else
diff --git a/bin/pulsar-admin-common.cmd b/bin/pulsar-admin-common.cmd
index e3f4754ea55..f2082f9bd8f 100644
--- a/bin/pulsar-admin-common.cmd
+++ b/bin/pulsar-admin-common.cmd
@@ -83,6 +83,30 @@ if %JAVA_MAJOR_VERSION% GEQ 11 (
REM Required by Netty for optimized direct byte buffer access
set "OPTS=%OPTS% --add-opens java.base/java.nio=ALL-UNNAMED --add-opens
java.base/jdk.internal.misc=ALL-UNNAMED"
)
+REM These two settings work together to ensure the Pulsar process exits
immediately and predictably
+REM if it runs out of either Java heap memory or its internal off-heap memory,
+REM as these are unrecoverable errors that require a process restart to clear
the faulty state and restore operation
+set "OPTS=-Dpulsar.allocator.exit_on_oom=true %OPTS%"
+REM Netty tuning
+REM These settings are primarily used to modify the Netty allocator
configuration,
+REM improving memory utilization and reducing the frequency of requesting
off-heap memory from the OS
+REM
+REM Based on the netty source code, the allocator's default chunk size is
calculated as:
+REM io.netty.allocator.pageSize (default: 8192) shifted left by
+REM io.netty.allocator.maxOrder (default: 9 after Netty 4.1.76.Final version).
+REM This equals 8192 * 2^9 = 4 MB:
+REM
https://github.com/netty/netty/blob/4.1/buffer/src/main/java/io/netty/buffer/PooledByteBufAllocator.java#L105
+REM
+REM Allocations that are larger than chunk size are considered huge
allocations and don't use the pool:
+REM
https://github.com/netty/netty/blob/4.1/buffer/src/main/java/io/netty/buffer/PoolArena.java#L141-L142
+REM
+REM Currently, Pulsar defaults to a maximum single message size of 5 MB.
+REM Therefore, when frequently producing messages whose size exceeds the chunk
size,
+REM Netty cannot utilize resources from the memory pool and must frequently
allocate native memory.
+REM This can lead to increased physical memory fragmentation and higher
reclamation costs.
+REM Thus, increasing io.netty.allocator.maxOrder to 10 to ensure that a single
message is larger
+REM than chunk size (8MB) and can reuse Netty's memory pool.
+set "OPTS=-Dio.netty.recycler.maxCapacityPerThread=4096
-Dio.netty.allocator.maxOrder=10 %OPTS%"
set "OPTS=-cp "%PULSAR_CLASSPATH%" %OPTS%"
set "OPTS=%OPTS% %PULSAR_EXTRA_OPTS%"
diff --git a/bin/pulsar-admin-common.sh b/bin/pulsar-admin-common.sh
index 366d76d7f5b..6052b4726e0 100755
--- a/bin/pulsar-admin-common.sh
+++ b/bin/pulsar-admin-common.sh
@@ -126,6 +126,30 @@ if [[ $JAVA_MAJOR_VERSION -ge 11 ]]; then
# Required by Netty for optimized direct byte buffer access
OPTS="$OPTS --add-opens java.base/java.nio=ALL-UNNAMED --add-opens
java.base/jdk.internal.misc=ALL-UNNAMED"
fi
+# These two settings work together to ensure the Pulsar process exits
immediately and predictably
+# if it runs out of either Java heap memory or its internal off-heap memory,
+# as these are unrecoverable errors that require a process restart to clear
the faulty state and restore operation
+OPTS="-XX:+ExitOnOutOfMemoryError -Dpulsar.allocator.exit_on_oom=true $OPTS"
+# Netty tuning
+# These settings are primarily used to modify the Netty allocator
configuration,
+# improving memory utilization and reducing the frequency of requesting
off-heap memory from the OS
+#
+# Based on the netty source code, the allocator's default chunk size is
calculated as:
+# io.netty.allocator.pageSize (default: 8192) shifted left by
+# io.netty.allocator.maxOrder (default: 9 after Netty 4.1.76.Final version).
+# This equals 8192 * 2^9 = 4 MB:
+#
https://github.com/netty/netty/blob/4.1/buffer/src/main/java/io/netty/buffer/PooledByteBufAllocator.java#L105
+#
+# Allocations that are larger than chunk size are considered huge allocations
and don't use the pool:
+#
https://github.com/netty/netty/blob/4.1/buffer/src/main/java/io/netty/buffer/PoolArena.java#L141-L142
+#
+# Currently, Pulsar defaults to a maximum single message size of 5 MB.
+# Therefore, when frequently producing messages whose size exceeds the chunk
size,
+# Netty cannot utilize resources from the memory pool and must frequently
allocate native memory.
+# This can lead to increased physical memory fragmentation and higher
reclamation costs.
+# Thus, increasing io.netty.allocator.maxOrder to 10 to ensure that a single
message is larger
+# than chunk size (8MB) and can reuse Netty's memory pool.
+OPTS="-Dio.netty.recycler.maxCapacityPerThread=4096
-Dio.netty.allocator.maxOrder=10 $OPTS"
OPTS="-cp $PULSAR_CLASSPATH $OPTS"
diff --git a/bin/pulsar-perf b/bin/pulsar-perf
index 2b120cc2f94..1f9b25fd026 100755
--- a/bin/pulsar-perf
+++ b/bin/pulsar-perf
@@ -123,6 +123,30 @@ if [[ $JAVA_MAJOR_VERSION -ge 11 ]]; then
# Required by Netty for optimized direct byte buffer access
OPTS="$OPTS --add-opens java.base/java.nio=ALL-UNNAMED --add-opens
java.base/jdk.internal.misc=ALL-UNNAMED"
fi
+# These two settings work together to ensure the Pulsar process exits
immediately and predictably
+# if it runs out of either Java heap memory or its internal off-heap memory,
+# as these are unrecoverable errors that require a process restart to clear
the faulty state and restore operation
+OPTS="-XX:+ExitOnOutOfMemoryError -Dpulsar.allocator.exit_on_oom=true $OPTS"
+# Netty tuning
+# These settings are primarily used to modify the Netty allocator
configuration,
+# improving memory utilization and reducing the frequency of requesting
off-heap memory from the OS
+#
+# Based on the netty source code, the allocator's default chunk size is
calculated as:
+# io.netty.allocator.pageSize (default: 8192) shifted left by
+# io.netty.allocator.maxOrder (default: 9 after Netty 4.1.76.Final version).
+# This equals 8192 * 2^9 = 4 MB:
+#
https://github.com/netty/netty/blob/4.1/buffer/src/main/java/io/netty/buffer/PooledByteBufAllocator.java#L105
+#
+# Allocations that are larger than chunk size are considered huge allocations
and don't use the pool:
+#
https://github.com/netty/netty/blob/4.1/buffer/src/main/java/io/netty/buffer/PoolArena.java#L141-L142
+#
+# Currently, Pulsar defaults to a maximum single message size of 5 MB.
+# Therefore, when frequently producing messages whose size exceeds the chunk
size,
+# Netty cannot utilize resources from the memory pool and must frequently
allocate native memory.
+# This can lead to increased physical memory fragmentation and higher
reclamation costs.
+# Thus, increasing io.netty.allocator.maxOrder to 10 to ensure that a single
message is larger
+# than chunk size (8MB) and can reuse Netty's memory pool.
+OPTS="-Dio.netty.recycler.maxCapacityPerThread=4096
-Dio.netty.allocator.maxOrder=10 $OPTS"
OPTS="-cp $PULSAR_CLASSPATH $OPTS"
OPTS="$OPTS $PULSAR_EXTRA_OPTS"
diff --git a/conf/bkenv.sh b/conf/bkenv.sh
index 5e8c2572a58..2e66bcacde6 100644
--- a/conf/bkenv.sh
+++ b/conf/bkenv.sh
@@ -88,8 +88,7 @@ if [[ -z "$BOOKIE_GC_LOG" ]]; then
fi
fi
-# Extra options to be passed to the jvm
-BOOKIE_EXTRA_OPTS="${BOOKIE_EXTRA_OPTS:-"-Dio.netty.leakDetection.level=disabled
${PULSAR_EXTRA_OPTS:-"-Dio.netty.recycler.maxCapacityPerThread=4096"}"}"
+BOOKIE_EXTRA_OPTS="${BOOKIE_EXTRA_OPTS} ${PULSAR_EXTRA_OPTS}"
# Add extra paths to the bookkeeper classpath
# BOOKIE_EXTRA_CLASSPATH=
diff --git a/conf/pulsar_env.sh b/conf/pulsar_env.sh
index 2189c887623..530a08c0ed7 100755
--- a/conf/pulsar_env.sh
+++ b/conf/pulsar_env.sh
@@ -89,9 +89,6 @@ if [[ -z "$PULSAR_GC_LOG" ]]; then
fi
fi
-# Extra options to be passed to the jvm
-PULSAR_EXTRA_OPTS="${PULSAR_EXTRA_OPTS:-" -Dpulsar.allocator.exit_on_oom=true
-Dio.netty.recycler.maxCapacityPerThread=4096"}"
-
# Add extra paths to the bookkeeper classpath
# PULSAR_EXTRA_CLASSPATH=
diff --git a/conf/pulsar_tools_env.sh b/conf/pulsar_tools_env.sh
index 6020e0a863a..bc2b6e030d2 100755
--- a/conf/pulsar_tools_env.sh
+++ b/conf/pulsar_tools_env.sh
@@ -57,8 +57,7 @@ if [ -n "$PULSAR_MEM" ]; then
fi
PULSAR_MEM=${PULSAR_MEM:-"-Xmx128m -XX:MaxDirectMemorySize=128m"}
-# Extra options to be passed to the jvm
-PULSAR_EXTRA_OPTS="${PULSAR_MEM} ${PULSAR_GC} ${PULSAR_GC_LOG}
-Dio.netty.leakDetection.level=disabled ${PULSAR_EXTRA_OPTS}"
+PULSAR_EXTRA_OPTS="${PULSAR_MEM} ${PULSAR_GC} ${PULSAR_GC_LOG}
${PULSAR_EXTRA_OPTS}"
# Add extra paths to the bookkeeper classpath
# PULSAR_EXTRA_CLASSPATH=
diff --git a/deployment/terraform-ansible/templates/pulsar_env.sh
b/deployment/terraform-ansible/templates/pulsar_env.sh
index 2638718ee55..6cda804f94a 100644
--- a/deployment/terraform-ansible/templates/pulsar_env.sh
+++ b/deployment/terraform-ansible/templates/pulsar_env.sh
@@ -47,9 +47,6 @@ PULSAR_MEM=" -Xms{{ max_heap_memory }} -Xmx{{ max_heap_memory
}} -XX:MaxDirectMe
# Garbage collection options
PULSAR_GC=" -XX:+UseZGC -XX:+PerfDisableSharedMem -XX:+AlwaysPreTouch"
-# Extra options to be passed to the jvm
-PULSAR_EXTRA_OPTS="-Dio.netty.leakDetection.level=disabled
-Dio.netty.recycler.maxCapacityPerThread=4096 ${PULSAR_EXTRA_OPTS}"
-
# Add extra paths to the bookkeeper classpath
# PULSAR_EXTRA_CLASSPATH=
diff --git
a/pulsar-common/src/test/java/org/apache/pulsar/common/allocator/PulsarByteBufAllocatorDefaultTest.java
b/pulsar-common/src/test/java/org/apache/pulsar/common/allocator/PulsarByteBufAllocatorDefaultTest.java
index 961c6f0176d..f19f4a38ac2 100644
---
a/pulsar-common/src/test/java/org/apache/pulsar/common/allocator/PulsarByteBufAllocatorDefaultTest.java
+++
b/pulsar-common/src/test/java/org/apache/pulsar/common/allocator/PulsarByteBufAllocatorDefaultTest.java
@@ -23,6 +23,8 @@ import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import io.netty.buffer.ByteBufAllocator;
+import io.netty.buffer.PooledByteBufAllocator;
+import io.netty.buffer.PooledByteBufAllocatorMetric;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.bookkeeper.common.allocator.OutOfMemoryPolicy;
@@ -54,4 +56,38 @@ public class PulsarByteBufAllocatorDefaultTest {
}
}
+ /**
+ * Verify that a {@link PooledByteBufAllocator} created with {@code
maxOrder=10} produces the expected chunk size,
+ * which is consistent with the {@code -Dio.netty.allocator.maxOrder=10}
setting in {@code conf/pulsar_env.sh}.
+ *
+ * <p>Netty computes chunk size as: {@code pageSize << maxOrder = 8192 <<
10 = 8,388,608 bytes (8 MiB)}.
+ * This test constructs the allocator directly with {@code maxOrder=10} so
no JVM argument is required.
+ */
+ @Test
+ public void testDefaultChunkSizeMatchesMaxOrder10() {
+ // Expected chunk size: pageSize (8192 bytes) << maxOrder (10) = 8 MiB
+ final int maxOrder = 10;
+ final int expectedChunkSize = 8192 << maxOrder;
+
+ // Create a PooledByteBufAllocator with maxOrder=10, same as
-Dio.netty.allocator.maxOrder=10
+ PooledByteBufAllocator allocator = new PooledByteBufAllocator(
+ true, // preferDirect
+ 0, // nHeapArena
+ 1, // nDirectArena
+ 8192, // pageSize (default)
+ maxOrder, // maxOrder=10
+ 64, // smallPageSize (default)
+ 256, // normalPageSize (default)
+ false,
+ 0
+ );
+
+ PooledByteBufAllocatorMetric metric = allocator.metric();
+ // Verify that the chunk size derived from maxOrder=10 equals 8 MiB
+ assertEquals(metric.chunkSize(), expectedChunkSize,
+ "Chunk size should be 8 MiB (pageSize << maxOrder = 8192 <<
10) "
+ + "as configured by -Dio.netty.allocator.maxOrder=10
in pulsar_env.sh");
+
+ }
+
}
\ No newline at end of file
diff --git a/src/pulsar-io-gen.sh b/src/pulsar-io-gen.sh
index 2748d8b13c4..f72de767849 100755
--- a/src/pulsar-io-gen.sh
+++ b/src/pulsar-io-gen.sh
@@ -114,6 +114,30 @@ OPTS="-Djava.net.preferIPv4Stack=true $OPTS
-Dlog4j.configurationFile=`basename
if [[ $JAVA_MAJOR_VERSION -ge 23 ]]; then
OPTS="--sun-misc-unsafe-memory-access=allow $OPTS"
fi
+# These two settings work together to ensure the Pulsar process exits
immediately and predictably
+# if it runs out of either Java heap memory or its internal off-heap memory,
+# as these are unrecoverable errors that require a process restart to clear
the faulty state and restore operation
+OPTS="-XX:+ExitOnOutOfMemoryError -Dpulsar.allocator.exit_on_oom=true $OPTS"
+# Netty tuning
+# These settings are primarily used to modify the Netty allocator
configuration,
+# improving memory utilization and reducing the frequency of requesting
off-heap memory from the OS
+#
+# Based on the netty source code, the allocator's default chunk size is
calculated as:
+# io.netty.allocator.pageSize (default: 8192) shifted left by
+# io.netty.allocator.maxOrder (default: 9 after Netty 4.1.76.Final version).
+# This equals 8192 * 2^9 = 4 MB:
+#
https://github.com/netty/netty/blob/4.1/buffer/src/main/java/io/netty/buffer/PooledByteBufAllocator.java#L105
+#
+# Allocations that are larger than chunk size are considered huge allocations
and don't use the pool:
+#
https://github.com/netty/netty/blob/4.1/buffer/src/main/java/io/netty/buffer/PoolArena.java#L141-L142
+#
+# Currently, Pulsar defaults to a maximum single message size of 5 MB.
+# Therefore, when frequently producing messages whose size exceeds the chunk
size,
+# Netty cannot utilize resources from the memory pool and must frequently
allocate native memory.
+# This can lead to increased physical memory fragmentation and higher
reclamation costs.
+# Thus, increasing io.netty.allocator.maxOrder to 10 to ensure that a single
message is larger
+# than chunk size (8MB) and can reuse Netty's memory pool.
+OPTS="-Dio.netty.recycler.maxCapacityPerThread=4096
-Dio.netty.allocator.maxOrder=10 $OPTS"
OPTS="-cp $PULSAR_CLASSPATH $OPTS"
OPTS="$OPTS $PULSAR_EXTRA_OPTS"
diff --git
a/tests/integration/src/test/java/org/apache/pulsar/tests/integration/containers/PulsarContainer.java
b/tests/integration/src/test/java/org/apache/pulsar/tests/integration/containers/PulsarContainer.java
index 2dd750b60e3..e051211f645 100644
---
a/tests/integration/src/test/java/org/apache/pulsar/tests/integration/containers/PulsarContainer.java
+++
b/tests/integration/src/test/java/org/apache/pulsar/tests/integration/containers/PulsarContainer.java
@@ -300,8 +300,6 @@ public abstract class PulsarContainer<SelfT extends
PulsarContainer<SelfT>> exte
}
protected void initializePulsarExtraOpts() {
- appendToEnv("PULSAR_EXTRA_OPTS",
- "-Dpulsar.allocator.exit_on_oom=true
-Dio.netty.recycler.maxCapacityPerThread=4096");
}
protected boolean isCodeCoverageEnabled() {