Open wittyResry opened 5 years ago
Unreachable
Thread
Busy Monitor
Native Stack
加载的"com.lambdaworks.redis.protocol.CommandHandler"实例"0xbcfa49b0"占用了1,535,774,776 (85.55%)字节.其内存主要积累在由类加载"bootstrap class loader"加载的"java.lang.Object[]"实例"0xfb35f108".
关键字
com.lambdaworks.redis.protocol.CommandHandler
fixed: Synchronize access to transport buffer:
diff --git a/pom.xml b/pom.xml
index 43eb6ce3..16eb7011 100644
--- a/pom.xml
+++ b/pom.xml
@@ -8,8 +8,8 @@
</parent>
<groupId>biz.paluch.redis</groupId>
- <artifactId>lettuce</artifactId>
- <version>3.5.0.Final</version>
+ <artifactId>lettuce-fixed</artifactId>
+ <version>3.5.1.fixed</version>
<packaging>jar</packaging>
<name>lettuce</name>
@@ -54,7 +54,7 @@
<!-- You need a running redis+sentinel for all tests, therefore disabled by default -->
<skipTests>true</skipTests>
<github.site.upload.skip>true</github.site.upload.skip>
- <lettuce-release-version>3.5.0.Final</lettuce-release-version>
+ <lettuce-release-version>3.5.1.fixed</lettuce-release-version>
<netty-version>4.0.37.Final</netty-version>
</properties>
@@ -62,7 +62,7 @@
<connection>scm:git:https://github.com/mp911de/lettuce.git</connection>
<developerConnection>scm:git:https://github.com/mp911de/lettuce.git</developerConnection>
<url>http://github.com/mp911de/lettuce</url>
- <tag>3.5.0.Final</tag>
+ <tag>3.5.1.fixed</tag>
</scm>
<prerequisites>
diff --git a/src/main/java/com/lambdaworks/redis/protocol/CommandHandler.java b/src/main/java/com/lambdaworks/redis/protocol/CommandHandler.java
index 10fc41b0..bf4b6f5f 100644
--- a/src/main/java/com/lambdaworks/redis/protocol/CommandHandler.java
+++ b/src/main/java/com/lambdaworks/redis/protocol/CommandHandler.java
@@ -365,7 +365,7 @@ public class CommandHandler<K, V> extends ChannelDuplexHandler implements RedisC
throws Exception {
if (command.isCancelled()) {
- transportBuffer.remove(command);
+ removeFromTransportBuffer(command);
return;
}
@@ -394,7 +394,7 @@ public class CommandHandler<K, V> extends ChannelDuplexHandler implements RedisC
for (RedisCommand<K, V, ?> command : commands) {
if (command.isCancelled()) {
- transportBuffer.remove(command);
+ removeFromTransportBuffer(command);
continue;
}
@@ -425,7 +425,7 @@ public class CommandHandler<K, V> extends ChannelDuplexHandler implements RedisC
sentTimes.put(command, new SentReceived(nanoTime()));
queue.add(command);
}
- transportBuffer.remove(command);
+ removeFromTransportBuffer(command);
} catch (Exception e) {
command.setException(e);
command.cancel(true);
@@ -434,6 +434,15 @@ public class CommandHandler<K, V> extends ChannelDuplexHandler implements RedisC
}
}
+ private void removeFromTransportBuffer(RedisCommand<K, V, ?> command) {
+ try {
+ writeLock.lock();
+ transportBuffer.remove(command);
+ } finally {
+ writeLock.unlock();
+ }
+ }
+
private long nanoTime() {
return System.nanoTime();
}
Spring内存注入对象给出去后,必须要给一份BeanCopy,或者需要new一个对象给出去
public Map<String, String> getConfigByDisplayType(String displayType) {
- return loginTipConfigByDisplayTypeMap.get(displayType);
+ Map<String, String> map = loginTipConfigByDisplayTypeMap.get(displayType);
+ if (map != null) {
+ return Maps.newHashMap(map);
+ }
...
}
线上遇到一种特殊的情况,请求对方没有返回失败的错误码,但是被拦截了。这种情况下,通过分析下游的调用链路,猜想运行的调用链路。
1.导致启动加载超时,线程hang住,查看阻塞态线程
public void init(String dataItemName) {
// 缓存是否已经初始化
if (isInit(dataItemName)) {
return;
}
synchronized (this) {
if (!isInit(dataItemName)) {
// 调用远程加载器加载数据
DataLoaderResult<UniformModel> result = dataLoader.completeLoadData(dataItemName,
null, UniformModel.class);
List<UniformModel> masterdataVOs = result.getDataList();
// 初始化缓存
initCache(dataItemName, masterdataVOs);
// 设置变更序列号
setChangeLogSeq(dataItemName, result.getChangeLogSeq());
// 打印缓存
dumpCache(dataItemName, Integer.toString(getChangeLogSeq(dataItemName)));
}
}
}
2.排查方法
jstack
1 配置VPC对等链接,协议PING用的是ICMP协议,配置TCP协议不生效
2 NET安全组只针对ADP出方向,故需要配置ECS单体的白名单
3 VPC对等连接,配置完成后还需要配置路由,确保下一跳能找到
网络相关的内容需要补充
Netty用了ByteBuf,要用safeRelease释放内存
try {
String str = ByteArrayUtil.bytes2HexStr(bytes);
ByteBuf in = ByteBufAllocator.DEFAULT.directBuffer(str.getBytes().length);
byte[] bt = BCD.toBcdBytes(str);
in.writeBytes(bt);
Sl651DataPacket msg = decode(in);
return msg;
} finally {
//ReferenceCountUtil.safeRelease(buffer);
}
2023-04-14 10:23:09.791 ERROR ResourceLeakDetector - LEAK: ByteBuf.release() was not called before it's garbage-collected. See https://netty.io/wiki/reference-counted-objects.html for more information.
Recent access records:
Created at:
io.netty.buffer.PooledByteBufAllocator.newHeapBuffer(PooledByteBufAllocator.java:384)
io.netty.buffer.AbstractByteBufAllocator.heapBuffer(AbstractByteBufAllocator.java:169)
io.netty.buffer.AbstractByteBufAllocator.heapBuffer(AbstractByteBufAllocator.java:160)
反思
1、如何读懂上层的管理要求,再三强调的,要能做到。(比如9点半到、每周提交OKR、每周提交工时,按时提交周报,不要让老板催)多次强调的事项,要保证能完成,不要做不到位。
2、ip和端口,为什么一再强调不能自动创建的,但还会踩坑?
3、提交代码检查下核心改动点,不要引入bug。尽量不要在凌晨git push,哪个时候头脑不清晰,检查不够充分
ConcurrentMap源码不允许key或者value为null
ConcurrentHashMap都不可以插入null key和null value,使用中必须判空处理
HashTable的key和value不允许未null
测试