-
Notifications
You must be signed in to change notification settings - Fork 999
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
cmd/sync: allocate memory from sync.Pool instead of Chunk.NewOffPage to avoid stall problem #5497
cmd/sync: allocate memory from sync.Pool instead of Chunk.NewOffPage to avoid stall problem #5497
Conversation
9872447
to
913e5a9
Compare
@YinhaoHu Thank you very much for your contribution, but we think the following approach would be more appropriate. Line 76 in b51019d
In this line of code Line 362 in b51019d
we have hard-coded a block size of 10M, so we can directly use a fixed-size sync.pool to allocate memory.
|
913e5a9
to
87c1986
Compare
@zhijian-pro Good idea. I have updated this PR based on the more appropriate approach. |
87c1986
to
0e12449
Compare
It is best to adjust the |
0e12449
to
6a7a3e7
Compare
6a7a3e7
to
c28247d
Compare
All test cases in the |
@YinhaoHu If the size of the last block is smaller than the default block size, it should not be put back into the pool, otherwise it will cause panic when you get it. |
The capacity of each buf is always |
The last block returned when file A is downloaded may be removed from the pool when file B is downloaded. |
The New function of downloadBufPool is: New: func() interface{} {
buf := make([]byte, 0, downloadBufSize)
return &buf
}, And the capacity is always downloadBufSize. In your case, the buf might be sliced to length downloadBufSize/2 and returned to the pool after file A is downloaded. The buf would be got again for downloading file B. It is OK to slice it to length downloadBufSize which is not greater than its capacity. If I have got your point, you're meaning the code case below which does not panic: const downloadBufSize = 10 << 20
var downloadBufPool = sync.Pool{
New: func() interface{} {
buf := make([]byte, 0, downloadBufSize)
return &buf
},
}
func Main() {
downloadFileA()
downloadFileB()
}
func downloadFileA() {
buf := downloadBufPool.Get().(*[]byte)
*buf = (*buf)[:downloadBufSize/2]
// read file
printBuf("A", buf)
downloadBufPool.Put(buf)
}
func downloadFileB() {
buf := downloadBufPool.Get().(*[]byte)
*buf = (*buf)[:downloadBufSize]
// read file
printBuf("B", buf)
downloadBufPool.Put(buf)
}
func printBuf(name string, buf *[]byte) {
fmt.Printf("%v: len = %v, cap = %v\n", name, len(*buf), cap(*buf))
} Output: A: len = 5242880, cap = 10485760
B: len = 10485760, cap = 10485760 |
OK,I missed |
…to avoid stall problem (#5497)
…to avoid stall problem (#5497)
close #5492
All unit tests related to this update are adjusted and passed.
The case mentioned in the issue can also run now.