Golang tls服务器和客户端,避免重新连接时客户端上的高内存使用率
根据这些示例,我在这里设置了一个服务器和一个客户机,它使用带有自定义证书的TLS。 使用pprof分析内存使用情况表明,每次TLS客户端连接时,Alloc的数量都会增加。查看日志,确实存在很多这样的条目: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
# 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上收集分配的内存。natpprof
告诉您的是分配,而不是使用情况。是什么让你说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()
....