Skip to content

x/tools/go/packages: memory hungry in parsing the github.com/go-fonts/latin-modern module packages #57985

Open

Description

@zigo101

What version of Go are you using (go version)?

$ go version
go version go1.20rc3 linux/amd64

The version of the golang.org/x/tools module is v0.5.0.

Does this issue reproduce with the latest release?

Yes

What did you do?

main.go:

package main

import (
	"log"
	"runtime"
	"runtime/metrics"

	"golang.org/x/tools/go/packages"

	_ "github.com/go-fonts/latin-modern/lmmath"
)

func printUsedMemory(prefix string) {
	runtime.GC()

	samples := []metrics.Sample{
		{Name: "/memory/classes/total:bytes"},
		{Name: "/memory/classes/heap/free:bytes"},
		{Name: "/memory/classes/heap/objects:bytes"},
		{Name: "/gc/heap/goal:bytes"},
	}
	metrics.Read(samples)
	
	log.Println("=========", prefix)
	for _, s := range samples {
		log.Printf("%44s %dMiB", s.Name, s.Value.Uint64()>>20)
	}
}

var allPkgs []*packages.Package

func main() {
	log.SetFlags(0)

	var configForParsing = &packages.Config{
		Mode: packages.NeedName | packages.NeedImports | packages.NeedDeps |
			packages.NeedTypes | packages.NeedExportsFile | packages.NeedFiles |
			packages.NeedCompiledGoFiles | packages.NeedTypesSizes |
			packages.NeedSyntax | packages.NeedTypesInfo,
		Tests: false,
	}

	printUsedMemory("before parsing:")

	pkgs, err := packages.Load(configForParsing, "github.com/go-fonts/latin-modern/...")
	if err != nil {
		log.Println("packages.Load (parse packages): %w", err)
		return
	}

	printUsedMemory("after parsing:")

	allPkgs = pkgs
}

go,mod:

module a.b/c

go 1.20

require golang.org/x/tools v0.5.0

require github.com/go-fonts/latin-modern v0.2.0

require (
	golang.org/x/mod v0.7.0 // indirect
	golang.org/x/sys v0.4.0 // indirect
)

Output:

========= before parsing:
                 /memory/classes/total:bytes 11MiB
             /memory/classes/heap/free:bytes 0MiB
          /memory/classes/heap/objects:bytes 0MiB
                         /gc/heap/goal:bytes 4MiB
========= after parsing:
                 /memory/classes/total:bytes 3079MiB
             /memory/classes/heap/free:bytes 1290MiB
          /memory/classes/heap/objects:bytes 1669MiB
                         /gc/heap/goal:bytes 3338MiB

What did you expect to see?

About several hundred of memory consumed.

What did you see instead?

About 3G memory consumed.

Each of the font source files only contains a var TTF = []byte{...} variable.
It is unexpected to use so much memory.

When parsing the packages in the github.com/tdewolff/canvas module,
which depends on the github.com/go-fonts/latin-modern module,
my computer (8G memory) hangs for virtual memory are swapped in and out frequently.

The github.com/tdewolff/canvas module is a relative small module.
My computer is able to parse much larger modules.

Activity

  1. added
    ToolsThis label describes issues relating to any tools in the x/tools repository.
    on Jan 25, 2023
  2. added this to the Unreleased milestone on Jan 25, 2023
  3. added
    NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.
    on Jan 30, 2023
  4. mknyszek commented on Jan 30, 2023

    @mknyszek
    Contributor

    CC @golang/tools-team

  5. findleyr commented on Jan 30, 2023

    @findleyr
    Contributor

    CC @griesemer @adonovan

    This is almost certainly caused by recording information in types.Info for each element of those byte literals. We could potentially optimize go/types for such cases.

  6. modified the milestones: Unreleased, Go1.21 on Jan 31, 2023
  7. findleyr commented on Jan 31, 2023

    @findleyr
    Contributor

    Tentatively marking this for Go 1.21, to see if we can improve memory consumption in go/types in these cases.

  8. modified the milestones: Go1.21, Go1.22 on Aug 8, 2023
  9. modified the milestones: Go1.22, Go1.23 on Feb 6, 2024
  10. modified the milestones: Go1.23, Go1.24 on Aug 13, 2024
  11. modified the milestones: Go1.24, Go1.25 on Feb 11, 2025
  12. modified the milestones: Go1.25, Go1.26 on Aug 12, 2025
  13. modified the milestones: Go1.26, Go1.27 on Dec 30, 2025
  14. modified the milestones: Go1.27, Go1.28 on Aug 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.PerformanceToolsThis label describes issues relating to any tools in the x/tools repository.

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions