-
Notifications
You must be signed in to change notification settings - Fork 167
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
possible memory leak using sjson.Set #51
Comments
I wrote a program that tried to reproduce the issue, but I wasn't able to see the memory issues that you were seeing. I took your example function and hardcoded the values that came from the Here's the complete program: package main
import (
"fmt"
"log"
"runtime"
"strconv"
"time"
"github.com/tidwall/sjson"
)
func main() {
evs := make(chan string, 100)
go func() {
var totalBytes int64
var totalEvents int64
ticker := time.NewTicker(time.Second)
for {
select {
case ev := <-evs:
totalEvents++
totalBytes += int64(len(ev))
case <-ticker.C:
var stats runtime.MemStats
runtime.ReadMemStats(&stats)
fmt.Printf(
"Processes %d Messages (%0.2f GB), Heap Size: %0.2f MB\n",
totalEvents,
float64(totalBytes)/1024/1024/1024,
float64(stats.HeapAlloc)/1024/1024,
)
}
}
}()
for i := 0; i < runtime.NumCPU(); i++ {
go func() {
for {
evs <- EnrichEvent("{}")
}
}()
}
select {}
}
// func EnrichEvent(event string, ctx *fasthttp.RequestCtx) string {
func EnrichEvent(event string) string {
// startTime := time.Now().UnixNano() / 1000000
// log := zap.L()
// ua := string(ctx.UserAgent())
ua := "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36"
// ip := ctx.RemoteIP().String()
ip := "127.10.105.81:98172"
entryTs := strconv.Itoa(int(time.Now().UnixNano() / int64(time.Millisecond)))
var err error
// add new fields to events
event, err = sjson.Set(event, "ua", ua)
if err != nil {
// log.Error("could not add ua to event", zap.String("event", event), zap.Error(err))
log.Fatal("could not add ua to event", event, err)
}
event, err = sjson.Set(event, "client_ip", ip)
if err != nil {
// log.Error("could not add client_ip to event", zap.String("event", event), zap.Error(err))
log.Fatal("could not add client_ip to event", event, err)
}
event, err = sjson.Set(event, "entry_ts", entryTs)
if err != nil {
// log.Error("could not add entry_ts to event", zap.String("event", event), zap.Error(err))
log.Fatal("could not add entry_ts to event", event, err)
}
// endTime := time.Now().UnixNano() / 1000000
// promy.RecordMetric("EnrichTimeHistogram", 0, float64(endTime-startTime), nil)
return event
} The program processes as many events as possible over a number of goroutines and prints out stats every second. Here's what I'm seeing:
After about 30 seconds, 30 million sjson.Set calls were processed with amounted to 5 GB of data. Yet the Go heap never goes above 4 MB. |
Hi @tidwall
I'm using this library to enrich event without unmarshalling into Go struct, and there's seems to be a memory problem in sjson.Set().
This is how I use it:
and when I'm trying to profile the allocs, it looks like sjson keeps growing and growing:
am I doing anything wrong?
The text was updated successfully, but these errors were encountered: