Skip to content

Memory leak in global MeterProvider #5753

@dashpole

Description

@dashpole

Description

Forked from open-telemetry/opentelemetry-go-contrib#5190

I am able to reproduce the issue with these benchmarks:

package bench

import (
	"testing"

	"go.opentelemetry.io/otel"
)

const (
	meterName   = "foo"
	metricName  = "bar"
)

func BenchmarkSimple(b *testing.B) {
	b.ReportAllocs()
	meter := otel.Meter(meterName)
	for i := 0; i < b.N; i++ {
		meter.Int64Counter(metricName)
	}
}

It has 1 allocation. Since we are repeatedly creating the same instrument, it should have 0 allocations. If I replace otel.Meter with a noop meterprovider or the real meter provider, it has 0 allocations. I believe the root cause is that we always append the instrument to the list of instruments for the global meter provider: e.g.

m.instruments = append(m.instruments, i)

We should instead maintain a map of instruments, and ensure that we only keep unique instruments, similar to what we did for the SDK.

Expected behavior

We should not leak memory when a user creates the same instrument repeatedly

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions