Repository: pingcap/tidb
File: util/memory/tracker.go (Go)

Code before:
		// we wouldn't maintain its children in order to avoiding mutex contention.
		children map[int][]*Tracker
	}
	actionMuForHardLimit actionMu
	actionMuForSoftLimit actionMu
	parMu                struct {
		sync.Mutex
		parent *Tracker // The parent memory tracker.
	}

	label         int   // Label of this "Tracker".
	bytesConsumed int64 // Consumed bytes.
	bytesLimit    atomic.Value
	maxConsumed   atomicutil.Int64 // max number of bytes consumed during execution.
	isGlobal      bool             // isGlobal indicates whether this tracker is global tracker
}

type actionMu struct {
	sync.Mutex
	actionOnExceed ActionOnExceed
}

// softScale means the scale of the soft limit to the hard limit.
const softScale = 0.8

// bytesLimits holds limit config atomically.
type bytesLimits struct {
	bytesHardLimit int64 // bytesHardLimit <= 0 means no limit, used for actionMuForHardLimit.
	bytesSoftLimit int64 // bytesSoftLimit <= 0 means no limit, used for actionMuForSoftLimit.
}

// InitTracker initializes a memory tracker.
//	1. "label" is the label used in the usage string.
//	2. "bytesLimit <= 0" means no limit.
// For the common tracker, isGlobal is default as false
func InitTracker(t *Tracker, label int, bytesLimit int64, action ActionOnExceed) {
	t.mu.children = nil
	t.actionMuForHardLimit.actionOnExceed = action
	t.actionMuForSoftLimit.actionOnExceed = nil
	t.parMu.parent = nil

	t.label = label
	t.bytesLimit.Store(&bytesLimits{
		bytesHardLimit: bytesLimit,
		bytesSoftLimit: int64(float64(bytesLimit) * softScale),
	})
	t.maxConsumed.Store(0)
	t.isGlobal = false
}

// NewTracker creates a memory tracker.

Review comment (suggestion):
The global variable EnableGCAwareMemoryTrack is initialized to false in the tracker.go file, but the default value DefEnableTiDBGCAwareMemoryTrack is set to true in tidb_vars.go. However, there's no initialization code that sets EnableGCAwareMemoryTrack to the default value at system startup. This means the feature will be disabled until a user explicitly sets the system variable, despite the default being true.

You need to add initialization code that loads the default value into EnableGCAwareMemoryTrack at system startup, similar to how other global variables are initialized.
```suggestion
var EnableGCAwareMemoryTrack = atomicutil.NewBool(true)
```

Code after:
		// The children memory trackers. If the Tracker is the Global Tracker, like executor.GlobalDiskUsageTracker,
		// we wouldn't maintain its children in order to avoiding mutex contention.
		children map[int][]*Tracker
	}
	actionMuForHardLimit actionMu
	actionMuForSoftLimit actionMu
	parMu                struct {
		sync.Mutex
		parent *Tracker // The parent memory tracker.
	}

	label         int   // Label of this "Tracker".
	bytesConsumed int64 // Consumed bytes.
	bytesReleased int64 // Released bytes.
	bytesLimit    atomic.Value
	maxConsumed   atomicutil.Int64 // max number of bytes consumed during execution.
	isGlobal      bool             // isGlobal indicates whether this tracker is global tracker
}

type actionMu struct {
	sync.Mutex
	actionOnExceed ActionOnExceed
}

// EnableGCAwareMemoryTrack is used to turn on/off the GC-aware memory track
var EnableGCAwareMemoryTrack = atomicutil.NewBool(false)

// https://golang.google.cn/pkg/runtime/#SetFinalizer
// It is not guaranteed that a finalizer will run if the size of *obj is zero bytes.
type finalizerRef struct {
	byte //nolint:unused
}

// softScale means the scale of the soft limit to the hard limit.
const softScale = 0.8

// bytesLimits holds limit config atomically.
type bytesLimits struct {
	bytesHardLimit int64 // bytesHardLimit <= 0 means no limit, used for actionMuForHardLimit.
	bytesSoftLimit int64 // bytesSoftLimit <= 0 means no limit, used for actionMuForSoftLimit.
}

// InitTracker initializes a memory tracker.
//	1. "label" is the label used in the usage string.
//	2. "bytesLimit <= 0" means no limit.
// For the common tracker, isGlobal is default as false
func InitTracker(t *Tracker, label int, bytesLimit int64, action ActionOnExceed) {
	t.mu.children = nil
	t.actionMuForHardLimit.actionOnExceed = action
	t.actionMuForSoftLimit.actionOnExceed = nil
	t.parMu.parent = nil