Golang tls服务器和客户端,避免重新连接时客户端上的高内存使用率

Golang tls服务器和客户端,避免重新连接时客户端上的高内存使用率,go,ssl,server,client,Go,Ssl,Server,Client,根据这些示例,我在这里设置了一个服务器和一个客户机,它使用带有自定义证书的TLS。 使用pprof分析内存使用情况表明,每次TLS客户端连接时,Alloc的数量都会增加。查看日志,确实存在很多这样的条目: # 0x5827cb math/big.nat.make+0x93b /usr/local/go/src/math/big/nat.go:68 # 0x58267e math/big.nat.mul+0x7ee

根据这些示例,我在这里设置了一个服务器和一个客户机,它使用带有自定义证书的TLS。 使用pprof分析内存使用情况表明,每次TLS客户端连接时,Alloc的数量都会增加。查看日志,确实存在很多这样的条目:

    #   0x5827cb    math/big.nat.make+0x93b                     /usr/local/go/src/math/big/nat.go:68
    #   0x58267e    math/big.nat.mul+0x7ee                      /usr/local/go/src/math/big/nat.go:428
    #   0x5780b8    math/big.(*Int).Mul+0x118                   /usr/local/go/src/math/big/int.go:168
    #   0x72d57b    crypto/elliptic.(*CurveParams).addJacobian+0xf5b        /usr/local/go/src/crypto/elliptic/elliptic.go:145
    #   0x72ebe2    crypto/elliptic.(*CurveParams).ScalarMult+0x1c2         /usr/local/go/src/crypto/elliptic/elliptic.go:260
    #   0x7c5934    crypto/tls.(*nistParameters).SharedKey+0xd4         /usr/local/go/src/crypto/tls/key_schedule.go:171
    #   0x7c3d09    crypto/tls.(*ecdheKeyAgreement).processServerKeyExchange+0x1d9  /usr/local/go/src/crypto/tls/key_agreement.go:266
    #   0x7a43e1    crypto/tls.(*clientHandshakeState).doFullHandshake+0x471    /usr/local/go/src/crypto/tls/handshake_client.go:503
    #   0x7a3b9a    crypto/tls.(*clientHandshakeState).handshake+0x3fa      /usr/local/go/src/crypto/tls/handshake_client.go:399
    #   0x7a21ec    crypto/tls.(*Conn).clientHandshake+0x2cc            /usr/local/go/src/crypto/tls/handshake_client.go:208
    #   0x7a07fe    crypto/tls.(*Conn).Handshake+0xee               /usr/local/go/src/crypto/tls/conn.go:1343
    #   0x7ca570    crypto/tls.DialWithDialer+0x220                 /usr/local/go/src/crypto/tls/tls.go:156
    #   0x8f2578    crypto/tls.Dial+0x1a8                       /usr/local/go/src/crypto/tls/tls.go:180
    #   0x8f2518    main.(*TCPSSLClient).Open+0x148                 /home/audinate/vcx/tcpSslClient.go:39
还有这些:

#   0x58364a    math/big.nat.make+0x2ca                     /usr/local/go/src/math/big/nat.go:68
#   0x583507    math/big.nat.sqr+0x187                      /usr/local/go/src/math/big/nat.go:570
#   0x578015    math/big.(*Int).Mul+0x75                    /usr/local/go/src/math/big/int.go:164
#   0x72e0e0    crypto/elliptic.(*CurveParams).doubleJacobian+0xe0      /usr/local/go/src/crypto/elliptic/elliptic.go:197
#   0x72eb7c    crypto/elliptic.(*CurveParams).ScalarMult+0x15c         /usr/local/go/src/crypto/elliptic/elliptic.go:258
#   0x7c5934    crypto/tls.(*nistParameters).SharedKey+0xd4         /usr/local/go/src/crypto/tls/key_schedule.go:171
#   0x7c3d09    crypto/tls.(*ecdheKeyAgreement).processServerKeyExchange+0x1d9  /usr/local/go/src/crypto/tls/key_agreement.go:266
#   0x7a43e1    crypto/tls.(*clientHandshakeState).doFullHandshake+0x471    /usr/local/go/src/crypto/tls/handshake_client.go:503
#   0x7a3b9a    crypto/tls.(*clientHandshakeState).handshake+0x3fa      /usr/local/go/src/crypto/tls/handshake_client.go:399
#   0x7a21ec    crypto/tls.(*Conn).clientHandshake+0x2cc            /usr/local/go/src/crypto/tls/handshake_client.go:208
#   0x7a07fe    crypto/tls.(*Conn).Handshake+0xee               /usr/local/go/src/crypto/tls/conn.go:1343
#   0x7ca570    crypto/tls.DialWithDialer+0x220                 /usr/local/go/src/crypto/tls/tls.go:156
#   0x8f2578    crypto/tls.Dial+0x1a8                       /usr/local/go/src/crypto/tls/tls.go:180
#   0x8f2518    main.(*TCPSSLClient).Open+0x148                 /home/audinate/vcx/tcpSslClient.go:39
做一个围棋工具和一个陀螺会让你觉得它很重要

Type: alloc_space
Time: Jul 19, 2019 at 3:03pm (CEST)
Entering interactive mode (type "help" for commands, "o" for options)
(pprof) top
Showing nodes accounting for 124.23MB, 96.13% of 129.23MB total
Dropped 34 nodes (cum <= 0.65MB)
Showing top 10 nodes out of 78
      flat  flat%   sum%        cum   cum%
  110.03MB 85.14% 85.14%   110.03MB 85.14%  math/big.nat.make
    3.53MB  2.73% 87.87%     6.47MB  5.00%  compress/flate.NewWriter
       2MB  1.55% 89.41%        2MB  1.55%  math/big.basicSqr
    1.80MB  1.39% 90.81%     2.94MB  2.28%  compress/flate.(*compressor).init
    1.50MB  1.16% 91.97%     1.50MB  1.16%  encoding/pem.removeWhitespace
    1.50MB  1.16% 93.13%    61.51MB 47.60%  crypto/elliptic.(*CurveParams).doubleJacobian
    1.14MB  0.88% 94.01%     1.14MB  0.88%  compress/flate.newDeflateFast
       1MB  0.77% 94.79%        1MB  0.77%  reflect.unsafe_NewArray
       1MB  0.77% 95.56%        1MB  0.77%  reflect.(*structType).Field
    0.73MB  0.57% 96.13%     0.73MB  0.57%  main.NewConmon
(pprof)

你的问题是什么?TLS握手需要内存分配,您感到惊讶吗?我没有。我并不惊讶它需要内存,但我很惊讶它每次连接时都会分配内存,而GC不会在math/big上收集分配的内存。nat
pprof
告诉您的是分配,而不是使用情况。是什么让你说GC没有收集内存?pprof显示分配了许多字节的运行计数器,没有更多,也没有更少。这并不意味着GC没有回收空间。//“我很惊讶它每次连接时都会分配内存。”这有什么奇怪的?用大数字做花哨的数学需要记忆。我不明白这怎么不明显。也许问题不清楚。随着时间的推移,我的程序确实获得了越来越多的内存(在linux上看“top”)。因此,一步一步地后退,我发现每次客户端连接时,它都会分配越来越多的内存。行中的值:“110.03MB 85.14%85.14%110.03MB 85.14%math/big.nat.make”正在快速增长。GC应该在这些“大”数字不再被引用时丢弃它们,不是吗?你的问题是什么?TLS握手需要内存分配,您感到惊讶吗?我没有。我并不惊讶它需要内存,但我很惊讶它每次连接时都会分配内存,而GC不会在math/big上收集分配的内存。nat
pprof
告诉您的是分配,而不是使用情况。是什么让你说GC没有收集内存?pprof显示分配了许多字节的运行计数器,没有更多,也没有更少。这并不意味着GC没有回收空间。//“我很惊讶它每次连接时都会分配内存。”这有什么奇怪的?用大数字做花哨的数学需要记忆。我不明白这怎么不明显。也许问题不清楚。随着时间的推移,我的程序确实获得了越来越多的内存(在linux上看“top”)。因此,一步一步地后退,我发现每次客户端连接时,它都会分配越来越多的内存。行中的值:“110.03MB 85.14%85.14%110.03MB 85.14%math/big.nat.make”正在快速增长。GC应该在这些“大”数字不再被引用时丢弃它们,不是吗?
   ....... 
   config := &tls.Config{Certificates: certificates, RootCAs: cas, SessionTicketsDisabled: true}


    conn, err := tls.Dial("tcp", addr, config)
    if err != nil {
        ...
        return
    }
    ....
    conn.Close()
    ....