美文网首页
dubbo内存泄漏源码解析

dubbo内存泄漏源码解析

作者: 程序猿皮皮 | 来源:发表于2021-11-01 14:53 被阅读0次

    第一步:privoder进程停止

    privoder进程停止,zk上节点被删除,consumer收到EMPTY开头的通知,然后开始销毁所有的Invoker。

    1、com.alibaba.dubbo.registry.integration.RegistryDirectory#refreshInvoker

    if (invokerUrls != null && invokerUrls.size() == 1 && invokerUrls.get(0) != null

            && Constants.EMPTY_PROTOCOL.equals(invokerUrls.get(0).getProtocol())) {

        this.forbidden = true; // Forbid to access

        this.methodInvokerMap = null; // Set the method invoker map to null

        destroyAllInvokers(); // Close all invokers   开始销毁所有的Invoker

    }

    2、com.alibaba.dubbo.remoting.exchange.support.header.HeaderExchangeChannel#close(int)

    if (closed) {

        return;

    }

    closed = true;

    3、com.alibaba.dubbo.rpc.protocol.dubbo.ReferenceCountExchangeClient#close(int)

    if (refenceCount.decrementAndGet() <= 0) {

                if (timeout == 0) {

                    client.close();

                } else {

                    client.close(timeout);

                }

                client = replaceWithLazyClient();

            }

    4、com.alibaba.dubbo.rpc.protocol.dubbo.ReferenceCountExchangeClient#replaceWithLazyClient

    LazyConnectExchangeClient gclient = ghostClientMap.get(key);

            if (gclient == null || gclient.isClosed()) {

                gclient = new LazyConnectExchangeClient(lazyUrl, client.getExchangeHandler());

                ghostClientMap.put(key, gclient);

            }

            return gclient;

    第二步:provider启动

    provider启动,zk节点重建,congsumer收到通知开始获取连接

    1、com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol#getSharedClient

    String key = url.getAddress();

           ReferenceCountExchangeClient client = referenceClientMap.get(key);

           if (client != null) {

               if (!client.isClosed()) {//  重点重点!!!

                   client.incrementAndGetCount();

                   return client;

               } else {

                   referenceClientMap.remove(key);

               }

           }

           locks.putIfAbsent(key, new Object());

           synchronized (locks.get(key)) {

               if (referenceClientMap.containsKey(key)) {

                   return referenceClientMap.get(key);

               }

               ExchangeClient exchangeClient = initClient(url);

               client = new ReferenceCountExchangeClient(exchangeClient, ghostClientMap);

               referenceClientMap.put(key, client);

               ghostClientMap.remove(key);

               locks.remove(key);

               return client;

           }

       }

    因为此时client实际上是LazyConnectExchangeClient类型的,它的属性也叫client,此时为null,看看它的isClose方法。

    com.alibaba.dubbo.rpc.protocol.dubbo.LazyConnectExchangeClient#isClosed

    public boolean isClosed() {

            if (client != null)

                return client.isClosed();

            else

                return true; // client为空,认为是关闭的。

        }

    2、com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol#getSharedClient开始执行后续的initClient方法,创建了NettyClient等对象。

        String key = url.getAddress();

        locks.putIfAbsent(key, new Object());

        synchronized (locks.get(key)) {

            if (referenceClientMap.containsKey(key)) {

                return referenceClientMap.get(key);

            }

            ExchangeClient exchangeClient = initClient(url);

            client = new ReferenceCountExchangeClient(exchangeClient, ghostClientMap);

            referenceClientMap.put(key, client);

            ghostClientMap.remove(key);

            locks.remove(key);

            return client;

        }

    }

    3、NettyClient与Bootstrap循环引用导致对象不能回收

    相关文章

      网友评论

          本文标题:dubbo内存泄漏源码解析

          本文链接:https://www.haomeiwen.com/subject/onbzaltx.html