-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Server memory pool metrics updates #63032
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR introduces comprehensive improvements to the server memory pool system with enhanced metrics capabilities and configuration options. The key motivation is to provide better observability and tracking of memory pool usage across different components.
- Adds
MemoryPoolOptions
class to enable specifying an owner for memory pools, improving metrics tagging and diagnostics - Replaces the old
PinnedBlockMemoryPoolMetrics
with a new sharedMemoryPoolMetrics
instance registered in DI, centralizing metric collection - Updates all metric names based on OpenTelemetry semantic conventions feedback and changes counter types from
uint
toulong
to prevent overflow
Reviewed Changes
Copilot reviewed 26 out of 26 changed files in this pull request and generated 1 comment.
Show a summary per file
File | Description |
---|---|
PinnedBlockMemoryPoolMetrics.cs | Removed old metrics class that was specific to pinned block pools |
MemoryPoolMetrics.cs | New shared metrics class with owner tagging support and updated metric names |
PinnedBlockMemoryPool.cs | Updated to use new metrics system and changed counter types to ulong |
IMemoryPoolFactory.cs / MemoryPoolOptions.cs | Added new interface signature and options class for pool configuration |
Various transport files | Updated to pass MemoryPoolOptions with appropriate owner identifiers |
DI registration files | Added MemoryPoolMetrics to dependency injection containers |
Test files | Updated tests to work with new metrics system and verify owner tagging |
/// <param name="options">Options for configuring the memory pool.</param> | ||
/// <returns>A new memory pool instance.</returns> | ||
MemoryPool<T> Create(); | ||
MemoryPool<T> Create(MemoryPoolOptions options); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking this should be optional so you don't have to new up options every time you create a pool? Are your thoughts that since you shouldn't be creating a new pool very often it's fine to require the small allocation cost?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_usedMemoryCounter = _meter.CreateUpDownCounter<long>( | ||
UsedMemoryName, | ||
unit: "By", | ||
description: "Number of bytes that are currently used by the pool."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think "currently stored by the pool."
would be less ambiguous.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think of aspnetcore.memory_pool.used
vs aspnetcore.memory_pool.pooled
?
The used
name came from another metric: jvm.memory.used
. But if I think about it more, the meaning is different here. jvm.memory.used
reports how much memory is used vs this metric which is how much memory is sitting idle in the pool.
For example, name and description could be:
_usedMemoryCounter = _meter.CreateUpDownCounter<long>(
"aspnetcore.memory_pool.pooled",
unit: "By",
description: "Number of bytes currently held by the pool and available for reuse.");
_endpoint = endpoint; | ||
_options = options; | ||
_memoryPool = options.MemoryPoolFactory.Create(); | ||
_memoryPool = options.MemoryPoolFactory.Create(new MemoryPoolOptions { Owner = "kestrel" }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should these be more specific; kestrel_namedpipe
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Originally I had them be specific, e.g. "namedpipe", but the memory pool is set on the connection that is created, which is then used throughout Kestrel for other reasons. I think it would be confusing if a memory pool that says it is owned by named pipes transport is then used by HTTPs middleware for example.
Changes still look good 👍 |
/azp run |
Azure Pipelines successfully started running 3 pipeline(s). |
Changes:
MemoryPoolOptions
so an owner can be specified when creating a memory pool withIMemoryPoolFactory.Create(MemoryPoolOptions)
. [API Proposal]: PinnedBlockMemoryPool metrics #61594MemoryPoolMetrics
to DI and resolve from DI instead ofIMeterFactory
. This means pools will use a shared instance ofMemoryPoolMetrics
.uint
counts in memory pool toulong
to prevent overflow possibility under heavy, sustained usage