copernet / copernicus

An alternative implementation of the Bitcoin Cash protocol, written in Golang
https://copernet.io
BSD 2-Clause "Simplified" License
85 stars 34 forks source link

Fix memory leak in Server.connectedPeers #233

Closed whunmr closed 5 years ago

whunmr commented 5 years ago

Find memory leaks on testnet server.

root@:~# ps -eo size,pid,user,command --sort -size | awk '{ hr=$1/1024 ; printf("%13.2f Mb ",hr) } { for ( x=4 ; x<=NF ; x++ ) { printf("%s ",$x) } print "" }' |cut -d "" -f2 | cut -d "-" -f1
      1505.89 Mb ./copernicus
root@:~/.bitcoincash/testnet# go tool pprof http://localhost:6060/debug/pprof/heap
Fetching profile over HTTP from http://localhost:6060/debug/pprof/heap
Saved profile in /root/pprof/pprof.copernicus.alloc_objects.alloc_space.inuse_objects.inuse_space.002.pb.gz
File: copernicus
Build ID: dd1af6b53bbb9e276602e6cd5ea03f8e2f70a057
Type: inuse_space
Time: Dec 19, 2018 at 3:57pm (CST)
Entering interactive mode (type "help" for commands, "o" for options)
(pprof) top20 -cum
Showing nodes accounting for 661.82MB, 87.55% of 755.96MB total
Dropped 75 nodes (cum <= 3.78MB)
Showing top 20 nodes out of 88
      flat  flat%   sum%        cum   cum%
         0     0%     0%   521.58MB 69.00%  main.appInitMain
         0     0%     0%   521.58MB 69.00%  main.bchMain
         0     0%     0%   521.58MB 69.00%  main.main
         0     0%     0%   521.58MB 69.00%  runtime.main
   10.84MB  1.43%  1.43%   507.18MB 67.09%  github.com/copernet/copernicus/logic/lblockindex.LoadBlockIndexDB
         0     0%  1.43%   421.83MB 55.80%  github.com/copernet/copernicus/persist/blkdb.(*BlockTreeDB).LoadBlockIndexGuts
   89.25MB 11.81% 13.24%   421.83MB 55.80%  github.com/copernet/copernicus/persist/blkdb.insertBlockIndex
  333.08MB 44.06% 57.30%   333.08MB 44.06%  github.com/copernet/copernicus/model/blockindex.NewBlockIndex
         0     0% 57.30%   155.63MB 20.59%  github.com/copernet/copernicus/net/server.(*Server).outboundPeerConnected
         0     0% 57.30%   155.63MB 20.59%  github.com/copernet/copernicus/net/server.(*Server).outboundPeerConnected-fm
         0     0% 57.30%   135.13MB 17.88%  github.com/copernet/copernicus/peer.NewOutboundPeer
  133.63MB 17.68% 74.98%   135.13MB 17.88%  github.com/copernet/copernicus/peer.newPeerBase
         0     0% 74.98%    74.50MB  9.86%  math/big.(*Int).Add
         0     0% 74.98%    74.50MB  9.86%  math/big.nat.add
   74.50MB  9.86% 84.83%    74.50MB  9.86%  math/big.nat.make
         0     0% 84.83%    20.64MB  2.73%  github.com/copernet/copernicus/net/syncmanager.(*SyncManager).messagesHandler
       4MB  0.53% 85.36%    19.14MB  2.53%  github.com/copernet/copernicus/peer.(*Peer).inHandler
   16.51MB  2.18% 87.55%    16.51MB  2.18%  runtime.malg
         0     0% 87.55%    16.51MB  2.18%  runtime.mstart
         0     0% 87.55%    16.51MB  2.18%  runtime.newproc.func1
(pprof) list Server.outboundPeerConnected
Total: 755.96MB
(pprof) list Server.*outboundPeerConnected
Total: 755.96MB
ROUTINE ======================== github.com/copernet/copernicus/net/server.(*Server).outboundPeerConnected in /root/go/src/github.com/copernet/copernicus/net/server/server.go
         0   155.63MB (flat, cum) 20.59% of Total
         .          .   1988:// outbound connection is established.  It initializes a new outbound server
         .          .   1989:// peer instance, associates it with the relevant state such as the connection
         .          .   1990:// request instance and the connection itself, and finally notifies the address
         .          .   1991:// manager of the attempt.
         .          .   1992:func (s *Server) outboundPeerConnected(c *connmgr.ConnReq, conn net.Conn) {
         .    13.50MB   1993:   sp := newServerPeer(s, c.Permanent)
         .          .   1994:   isWhitelisted := isWhitelisted(conn.RemoteAddr())
         .   142.13MB   1995:   p, err := peer.NewOutboundPeer(newPeerConfig(sp), c.Addr.String(), isWhitelisted)
         .          .   1996:   if err != nil {
         .          .   1997:       log.Debug("Cannot create outbound peer %s: %v", c.Addr, err)
         .          .   1998:       s.connManager.Disconnect(c.ID())
         .          .   1999:   }
         .          .   2000:   sp.Peer = p
ROUTINE ======================== github.com/copernet/copernicus/net/server.(*Server).outboundPeerConnected-fm in /root/go/src/github.com/copernet/copernicus/net/server/server.go
         0   155.63MB (flat, cum) 20.59% of Total
         .          .   2653:       Dial: func(ctx context.Context, netaddr net.Addr) (net.Conn, error) {
         .          .   2654:           var d net.Dialer
         .          .   2655:           return d.DialContext(ctx, netaddr.Network(), netaddr.String())
         .          .   2656:       },
         .          .   2657:       OnAccept:  s.inboundPeerConnected,
         .   155.63MB   2658:       OnConnect: s.outboundPeerConnected,
         .          .   2659:       GetNewAddress: func() (net.Addr, error) {
         .          .   2660:           addr, err := amgr.NewAddress(func(groupKey string) bool {
         .          .   2661:               return s.OutboundGroupCount(groupKey) != 0
         .          .   2662:           })
         .          .   2663:           if err != nil {
(pprof) list lblockindex.LoadBlockIndexDB