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