You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@dubbo.apache.org by "finalcola (GitHub)" <gi...@apache.org> on 2019/08/20 03:06:12 UTC
[GitHub] [dubbo] finalcola opened issue #4890: invoker created by
AbstractProxyProtocol may cause memory leak
- [ ] I have searched the [issues](https://github.com/apache/dubbo/issues) of this repository and believe that this is not a duplicate.
- [ ] I have checked the [FAQ](https://github.com/apache/dubbo/blob/master/FAQ.md) of this repository and believe that this is not a duplicate.
### Environment
* Dubbo version: 2.7.x
* Operating System version: *
* Java version: *
### Steps to reproduce this issue
由AbstractProxyProtocol创建的invoker在调用destroy()销毁后,因为其destroy方法并不会清理资源,所以AbstractProtocol.invokers依然会持有该invoker的引用(invoker创建时会被添加到AbstractProtocol.invokers中)。
```
protected <T> Invoker<T> protocolBindingRefer(final Class<T> type, final URL url) throws RpcException {
final Invoker<T> target = proxyFactory.getInvoker(doRefer(type, url), type, url);
// AbstractInvoker.destroy方法只会更新isDestroyed字段,不会清理资源
Invoker<T> invoker = new AbstractInvoker<T>(type, url) {
@Override
protected Result doInvoke(Invocation invocation) throws Throwable {
try {
Result result = target.invoke(invocation);
// FIXME result is an AsyncRpcResult instance.
Throwable e = result.getException();
if (e != null) {
for (Class<?> rpcException : rpcExceptions) {
if (rpcException.isAssignableFrom(e.getClass())) {
throw getRpcException(type, url, invocation, e);
}
}
}
return result;
} catch (RpcException e) {
if (e.getCode() == RpcException.UNKNOWN_EXCEPTION) {
e.setCode(getErrorCode(e.getCause()));
}
throw e;
} catch (Throwable e) {
throw getRpcException(type, url, invocation, e);
}
}
};
// invoker会保存所有新建的invoker
invokers.add(invoker);
return invoker;
}
```
而DobboProtocol创建的invoker销毁时则会清除invokers中的引用:
```
public void destroy() {
// in order to avoid closing a client multiple times, a counter is used in case of connection per jvm, every
// time when client.close() is called, counter counts down once, and when counter reaches zero, client will be
// closed.
if (super.isDestroyed()) {
return;
} else {
// double check to avoid dup close
destroyLock.lock();
try {
if (super.isDestroyed()) {
return;
}
super.destroy();
// 从invokers中删除
if (invokers != null) {
invokers.remove(this);
}
for (ExchangeClient client : clients) {
try {
client.close(ConfigurationUtils.getServerShutdownTimeout());
} catch (Throwable t) {
logger.warn(t.getMessage(), t);
}
}
} finally {
destroyLock.unlock();
}
}
}
```
Pls. provide [GitHub address] to reproduce this issue.
### Expected Result
当invoker.destroy方法调用后,则该invoker应该从AbstractProtocol.invokers中remove掉(例如DubboInvoker的做法)。
### Actual Result
由于destroy方法中未将invoker从AbstractProtocol.invokers中删除,则会导致销毁的invoker无法被GC,内存泄漏
If there is an exception, please attach the exception trace:
```
Just put your stack trace here!
```
[ Full content available at: https://github.com/apache/dubbo/issues/4890 ]
This message was relayed via gitbox.apache.org for notifications@dubbo.apache.org
[GitHub] [dubbo] finalcola commented on issue #4890: invoker created
by AbstractProxyProtocol may cause memory leak
Posted by "finalcola (GitHub)" <gi...@apache.org>.
https://github.com/apache/dubbo/pull/4738#issue-304048243
[ Full content available at: https://github.com/apache/dubbo/issues/4890 ]
This message was relayed via gitbox.apache.org for notifications@dubbo.apache.org