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

High Mem & GC when compiling large cyclic data structure #516

Open
kaijietti opened this issue Jul 11, 2024 · 0 comments
Open

High Mem & GC when compiling large cyclic data structure #516

kaijietti opened this issue Jul 11, 2024 · 0 comments

Comments

@kaijietti
Copy link

kaijietti commented Jul 11, 2024

go.mod:

module gojsontest

go 1.21

require (
	github.com/goccy/go-json v0.10.3
	github.com/stripe/stripe-go/v79 v79.2.0
)

main.go:

package main

import (
	"fmt"
	"log"
	"net/http"
	_ "net/http/pprof"

	"github.com/goccy/go-json"
	"github.com/stripe/stripe-go/v79"
)

func main() {
	go func() {
		log.Println(http.ListenAndServe("localhost:6060", nil))
	}()

	bytes, err := json.Marshal(&stripe.CheckoutSession{})
	if err != nil {
		panic(err)
	}
	fmt.Println(string(bytes))
}

The above code stuck in func (c *Compiler) compile(typeptr uintptr) phase. Plenty of memory was allocated and then GC contributed most of the CPU time.

A pprof sample is here.
pprof.samples.cpu.001.pb.gz

And I used the following script to check how many cycle definition:

package main

import (
	"fmt"
	"reflect"

	"github.com/stripe/stripe-go/v79"
)

func findTypeCycle(t reflect.Type, visited map[reflect.Type]bool, cycleCount *int) {
	if visited[t] {
		*cycleCount++
		return
	}

	visited[t] = true
	defer delete(visited, t)

	for i := 0; i < t.NumField(); i++ {
		field := t.Field(i)
		fieldType := field.Type

		if fieldType.Kind() == reflect.Ptr {
			fieldType = fieldType.Elem()
		}

		if fieldType.Kind() == reflect.Struct {
			findTypeCycle(fieldType, visited, cycleCount)
		}
	}
}

func main() {
	cycleCount := 0
	findTypeCycle(reflect.TypeOf(stripe.CheckoutSession{}), make(map[reflect.Type]bool), &cycleCount)
	fmt.Printf("Total number of cycles detected: %d\n", cycleCount)
}

And the output is:

Total number of cycles detected: 1083720
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant