Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lockFreeQueue的gc问题 #283

Open
zhu121 opened this issue Dec 2, 2021 · 2 comments
Open

lockFreeQueue的gc问题 #283

zhu121 opened this issue Dec 2, 2021 · 2 comments
Assignees
Labels
enhancement New feature or request proposal Proposal for this repo
Milestone

Comments

@zhu121
Copy link

zhu121 commented Dec 2, 2021

lock_free_queue.go的Enqueue()函数内的n := &node{value: task}会调用到runtime.newobject和runtime.mallocgc,
Enqueue()频繁调用时,是否会有gc问题,是否考虑用类似sync.Pool的形式来管理node

@zhu121 zhu121 added enhancement New feature or request proposal Proposal for this repo labels Dec 2, 2021
@panjf2000
Copy link
Owner

你可以测一下,然后把数据贴出来看看,看看是不是的确会有很大影响。

@zhu121
Copy link
Author

zhu121 commented Dec 6, 2021

1.新增的测试代码/cmd/main.go

type testCodec struct {
}

func (cc *testCodec) Encode(c gnet.Conn, buf []byte) (out []byte, err error) {
	return buf, nil
}

func (cc *testCodec) Decode(c gnet.Conn) ([]byte, error) {
	var buf innerBuffer
	buf = c.Read()
	msg, _ := buf.readN(4)
	if msg == nil {
		return nil, nil
	}
	c.ShiftN(4)
	return msg, nil
}

type testServer struct {
	*gnet.EventServer
	svr        gnet.Server
	protoAddr  string
	workerPool *goroutine.Pool
}

func (s *testServer) React(packet []byte, c gnet.Conn) (out []byte, action gnet.Action) {
	data := append([]byte{}, packet...)
	_ = s.workerPool.Submit(func() {
		_ = c.AsyncWrite(data)
	})
	return nil, gnet.None
}

func main() {
	f, _ := os.OpenFile("gate-cpu.pprof", os.O_CREATE|os.O_RDWR, 0644)
	_ = pprof.StartCPUProfile(f)
	defer func() {
		pprof.StopCPUProfile()
		f.Close()
	}()
	ts := &testServer{
		protoAddr:  "tcp4://0.0.0.0:9999",
		workerPool: goroutine.Default(),
	}
	go func() {
		time.Sleep(70 * time.Second)
		_ = gnet.Stop(context.TODO(), ts.protoAddr)
	}()
	err := gnet.Serve(ts,
		ts.protoAddr,
		gnet.WithLockOSThread(true),
		gnet.WithNumEventLoop(3),
		gnet.WithReuseAddr(true),
		gnet.WithTCPNoDelay(gnet.TCPNoDelay),
		gnet.WithCodec(&testCodec{}),
		gnet.WithLoadBalancing(gnet.LeastConnections))
	fmt.Println("serve", err)
}

2.go tool pprof数据:
Showing nodes accounting for 137.59s, 86.26% of 159.51s total
Dropped 228 nodes (cum <= 0.80s)
Showing top 10 nodes out of 65
flat flat% sum% cum cum%
83.39s 52.28% 52.28% 83.39s 52.28% runtime.futex
35.05s 21.97% 74.25% 36.85s 23.10% syscall.Syscall
13.13s 8.23% 82.48% 13.58s 8.51% syscall.Syscall6
1.17s 0.73% 83.22% 65.22s 40.89% github.com/panjf2000/gnet/internal/netpoll.(*Poller).Polling
0.92s 0.58% 83.79% 3.53s 2.21% runtime.mallocgc

3.runtime.mallocgc相关的调用
gnet(*Conn).AsyncWrite -> runtime.mallocgc
gnet(*Conn).AsyncWrite -> runtime.newobject -> runtime.mallocgc
gnet(*Conn).AsyncWrite -> netpoll(*Poller).Tigger -> runtime.newobject -> runtime.mallocgc
main(*testServer).React -> runtime.growslice -> runtime.mallocgc

@panjf2000 panjf2000 added this to the Long term milestone Jan 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request proposal Proposal for this repo
Projects
None yet
Development

No branches or pull requests

2 participants