mirror of
https://github.com/ii64/sonic.git
synced 2026-06-20 16:45:22 +08:00
fix: add gcGuard to prevent GC during Marshal()/Unmarshal() (#122)
Co-authored-by: duanyi.aster <duanyi.aster@bytedance.com>
This commit is contained in:
parent
fe56a21bf5
commit
3eade82a01
3 changed files with 72 additions and 1 deletions
|
|
@ -19,6 +19,7 @@ package decoder
|
|||
import (
|
||||
`encoding/json`
|
||||
`reflect`
|
||||
`runtime`
|
||||
|
||||
`github.com/bytedance/sonic/internal/rt`
|
||||
)
|
||||
|
|
@ -70,6 +71,9 @@ func (self *Decoder) Decode(val interface{}) error {
|
|||
/* return the stack back */
|
||||
self.i = nb
|
||||
freeStack(sb)
|
||||
|
||||
/* avoid GC ahead */
|
||||
runtime.KeepAlive(vv)
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -105,4 +109,4 @@ func (self *Decoder) DisallowUnknownFields() {
|
|||
func Pretouch(vt reflect.Type) (err error) {
|
||||
_, err = findOrCompile(rt.UnpackType(vt))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
@ -20,6 +20,7 @@ import (
|
|||
`bytes`
|
||||
`encoding/json`
|
||||
`reflect`
|
||||
`runtime`
|
||||
|
||||
`github.com/bytedance/sonic/internal/rt`
|
||||
)
|
||||
|
|
@ -102,6 +103,9 @@ func EncodeInto(buf *[]byte, val interface{}, opts Options) error {
|
|||
|
||||
/* return the stack into pool */
|
||||
freeStack(stk)
|
||||
|
||||
/* avoid GC ahead */
|
||||
runtime.KeepAlive(efv)
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
|||
63
issue_test/issue123_test.go
Normal file
63
issue_test/issue123_test.go
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright 2021 ByteDance Inc.
|
||||
*
|
||||
* 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 issue_test
|
||||
|
||||
import (
|
||||
`encoding/json`
|
||||
`fmt`
|
||||
`sync`
|
||||
`testing`
|
||||
|
||||
`github.com/bytedance/sonic`
|
||||
)
|
||||
|
||||
func TestGcWriteBarrier(t *testing.T) {
|
||||
// debug.SetGCPercent(-1)
|
||||
size := 10_0000
|
||||
data := make([]int, size)
|
||||
date, _ := json.Marshal(data)
|
||||
|
||||
// debug.SetGCPercent(-1)
|
||||
wg := sync.WaitGroup{}
|
||||
|
||||
for i := 0; i < 1000; i++ {
|
||||
wg.Add(1)
|
||||
cd := make([]byte, len(date))
|
||||
copy(cd, date)
|
||||
go func() {
|
||||
var w []int
|
||||
defer wg.Done()
|
||||
// Decode
|
||||
if err := sonic.Unmarshal(cd, &w); err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func BenchmarkGcGuard(b *testing.B) {
|
||||
size := 10_0000
|
||||
data := make([]int, size)
|
||||
date, _ := json.Marshal(data)
|
||||
b.RunParallel(func(p *testing.PB) {
|
||||
for p.Next() {
|
||||
var w []int
|
||||
_ = sonic.Unmarshal(date, &w)
|
||||
}
|
||||
})
|
||||
}
|
||||
Loading…
Reference in a new issue