From ecd4856dce99b4a2771f6f2916a33ed9cfa935bb Mon Sep 17 00:00:00 2001 From: "wangjiahua.wjh" Date: Wed, 10 Jun 2026 21:52:27 +0800 Subject: [PATCH] [ISSUE #10464] Avoid unnecessary allocation in Message.getProperty and NFE in getPriority - getProperty(): return null when properties map is uninitialized instead of creating an empty HashMap as a side-effect of a read-only call. - getPriority(): add null/empty fast-path before NumberUtils.toInt() to skip the NFE throw+catch when PRIORITY is unset (the common case). Co-Authored-By: Claude Opus 4.6 (1M context) --- .../broker/pop/PopConsumerService.java | 6 +++++- .../broker/processor/PopReviveService.java | 5 ++++- .../rocketmq/common/message/Message.java | 20 ++++++++++++++++--- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/broker/src/main/java/org/apache/rocketmq/broker/pop/PopConsumerService.java b/broker/src/main/java/org/apache/rocketmq/broker/pop/PopConsumerService.java index f72e2ba26f2..63e6c014903 100644 --- a/broker/src/main/java/org/apache/rocketmq/broker/pop/PopConsumerService.java +++ b/broker/src/main/java/org/apache/rocketmq/broker/pop/PopConsumerService.java @@ -25,6 +25,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Queue; import java.util.concurrent.CompletableFuture; @@ -729,7 +730,10 @@ public boolean reviveRetry(PopConsumerRecord record, MessageExt messageExt) { msgInner.setReconsumeTimes(messageExt.getReconsumeTimes() + 1); } - msgInner.getProperties().putAll(messageExt.getProperties()); + Map sourceProperties = messageExt.getProperties(); + if (sourceProperties != null) { + msgInner.getProperties().putAll(sourceProperties); + } // set first pop time here if (messageExt.getReconsumeTimes() == 0 || diff --git a/broker/src/main/java/org/apache/rocketmq/broker/processor/PopReviveService.java b/broker/src/main/java/org/apache/rocketmq/broker/processor/PopReviveService.java index 07f16e98965..ad8512c7aee 100644 --- a/broker/src/main/java/org/apache/rocketmq/broker/processor/PopReviveService.java +++ b/broker/src/main/java/org/apache/rocketmq/broker/processor/PopReviveService.java @@ -127,7 +127,10 @@ private boolean reviveRetry(PopCheckPoint popCheckPoint, MessageExt messageExt) } else { msgInner.setReconsumeTimes(messageExt.getReconsumeTimes() + 1); } - msgInner.getProperties().putAll(messageExt.getProperties()); + Map sourceProperties = messageExt.getProperties(); + if (sourceProperties != null) { + msgInner.getProperties().putAll(sourceProperties); + } if (messageExt.getReconsumeTimes() == 0 || msgInner.getProperties().get(MessageConst.PROPERTY_FIRST_POP_TIME) == null) { msgInner.getProperties().put(MessageConst.PROPERTY_FIRST_POP_TIME, String.valueOf(popCheckPoint.getPopTime())); } diff --git a/common/src/main/java/org/apache/rocketmq/common/message/Message.java b/common/src/main/java/org/apache/rocketmq/common/message/Message.java index b64f3520c16..821754d9dec 100644 --- a/common/src/main/java/org/apache/rocketmq/common/message/Message.java +++ b/common/src/main/java/org/apache/rocketmq/common/message/Message.java @@ -102,11 +102,21 @@ public String getUserProperty(final String name) { return this.getProperty(name); } + /** + * Returns the value of the named property, or {@code null} if the property is not set + * or the properties map has not been initialized. + *

+ * Note: this method is read-only and does not lazily initialize the internal + * properties map. To add properties, use {@link #putProperty(String, String)} which + * creates the map on demand. + * + * @param name the property key + * @return the property value, or {@code null} + */ public String getProperty(final String name) { if (null == this.properties) { - this.properties = new HashMap<>(); + return null; } - return this.properties.get(name); } @@ -164,7 +174,11 @@ public void setPriority(int priority) { } public int getPriority() { - return NumberUtils.toInt(this.getProperty(MessageConst.PROPERTY_PRIORITY), -1); + String value = this.getProperty(MessageConst.PROPERTY_PRIORITY); + if (value == null || value.isEmpty()) { + return -1; + } + return NumberUtils.toInt(value, -1); } public boolean isWaitStoreMsgOK() {