utils/pool: use sync.pool to reduce the pressure of garbage collection

This commit is contained in:
fatedier 2016-07-31 03:26:41 +08:00
parent df8edefa56
commit 7f386fc042
4 changed files with 77 additions and 6 deletions

View File

@ -26,6 +26,7 @@ import (
"frp/utils/conn" "frp/utils/conn"
"frp/utils/log" "frp/utils/log"
"frp/utils/pcrypto" "frp/utils/pcrypto"
"frp/utils/pool"
) )
// will block until connection close // will block until connection close
@ -115,7 +116,10 @@ func pipeDecrypt(r *conn.Conn, w *conn.Conn, conf config.BaseConf, needRecord bo
return fmt.Errorf("Pcrypto Init error: %v", err) return fmt.Errorf("Pcrypto Init error: %v", err)
} }
buf := make([]byte, 5*1024+4) // get []byte from buffer pool
buf := pool.GetBuf(5*1024 + 4)
defer pool.PutBuf(buf)
var left, res []byte var left, res []byte
var cnt int = -1 var cnt int = -1
@ -198,7 +202,10 @@ func pipeEncrypt(r *conn.Conn, w *conn.Conn, conf config.BaseConf, needRecord bo
}() }()
} }
buf := make([]byte, 5*1024) // get []byte from buffer pool
buf := pool.GetBuf(5*1024 + 4)
defer pool.PutBuf(buf)
for { for {
n, err := r.Read(buf) n, err := r.Read(buf)
if err != nil { if err != nil {

View File

@ -0,0 +1,58 @@
// Copyright 2016 fatedier, fatedier@gmail.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package pool
import "sync"
var (
bufPool5k sync.Pool
bufPool2k sync.Pool
bufPool1k sync.Pool
bufPool sync.Pool
)
func GetBuf(size int) []byte {
var x interface{}
if size >= 5*1024 {
x = bufPool5k.Get()
} else if size >= 2*1024 {
x = bufPool2k.Get()
} else if size >= 1*1024 {
x = bufPool1k.Get()
} else {
x = bufPool.Get()
}
if x == nil {
return make([]byte, size)
}
buf := x.([]byte)
if cap(buf) < size {
return make([]byte, size)
}
return buf[:size]
}
func PutBuf(buf []byte) {
size := cap(buf)
if size >= 5*1024 {
bufPool5k.Put(buf)
} else if size >= 2*1024 {
bufPool2k.Put(buf)
} else if size >= 1*1024 {
bufPool1k.Put(buf)
} else {
bufPool.Put(buf)
}
}

View File

@ -26,6 +26,7 @@ import (
"time" "time"
"frp/utils/conn" "frp/utils/conn"
"frp/utils/pool"
) )
type HttpMuxer struct { type HttpMuxer struct {
@ -61,9 +62,11 @@ func HttpHostNameRewrite(c *conn.Conn, rewriteHost string) (_ net.Conn, err erro
} }
func hostNameRewrite(request io.Reader, rewriteHost string) (_ []byte, err error) { func hostNameRewrite(request io.Reader, rewriteHost string) (_ []byte, err error) {
buffer := make([]byte, 1024) buf := pool.GetBuf(1024)
request.Read(buffer) defer pool.PutBuf(buf)
retBuffer, err := parseRequest(buffer, rewriteHost)
request.Read(buf)
retBuffer, err := parseRequest(buf, rewriteHost)
return retBuffer, err return retBuffer, err
} }

View File

@ -22,6 +22,7 @@ import (
"time" "time"
"frp/utils/conn" "frp/utils/conn"
"frp/utils/pool"
) )
const ( const (
@ -52,7 +53,9 @@ func NewHttpsMuxer(listener *conn.Listener, timeout time.Duration) (*HttpsMuxer,
} }
func readHandshake(rd io.Reader) (host string, err error) { func readHandshake(rd io.Reader) (host string, err error) {
data := make([]byte, 1024) data := pool.GetBuf(1024)
origin := data
defer pool.PutBuf(origin)
length, err := rd.Read(data) length, err := rd.Read(data)
if err != nil { if err != nil {
return return