Skip to content

MVC: Minimize memory consumption by routing data structures #60000

@AlexanderKot

Description

@AlexanderKot

Is there an existing issue for this?

  • I have searched the existing issues

Is your feature request related to a problem? Please describe the problem.

After startup our application consume significant amount of memory related to MVC routing.
It currently uses .net8.
There are 700+controllers with ~60 method per controller.
Most of controllers inherited from base generic controllers hierarchy, many controllers final type generated at runtime by closing opened generic base controller.
As result at runtime there are many controllers with same method names and parameter names.

After startup we can see next memory consumers:
Image

There are many duplicated strings in memory (~8% of all allocated objects), where strings referenced by MVC.routing take 1st, 3d, 5th, 9th ..... places

Image

Some examples with string referenced by routing structures directly.

Parameter name:

Value Wasted Count
cancellationToken 484,5 KB 14593

Image

Value Wasted Count
filterId 230,83 KB 14774
viewId 173,14 KB 14776

Image
Image

Http verb name:

Value Wasted Count
POST 120,36 KB 15407
GET 67,28 KB 11483

Image
Image

Controller action name:

Value Wasted Count
GetLayoutsPanelForPropertyGridAsync 50,11 KB 734

Image

Also sparse arrays related to MVC routing are in TOP of memory killers.

Image

Type Wasted Count
System.Collections.Concurrent.ConcurrentDictionary+VolatileNode<System.Type, System.Object[]>[] 11,83 MB 43118

99.9% of theses Dictionaries contains 1 element
Image

Type Wasted Count
System.Collections.Generic.Dictionary+Entry<System.String[], System.Collections.Generic.List<Microsoft.AspNetCore.Http.Endpoint>>[] 1,55 MB 2

Image

Type Wasted Count
Microsoft.AspNetCore.Http.Endpoint[] 1,11 MB 41485

Most of lists contains 1 element from 4 allocated by default
Image

Describe the solution you'd like

Some string.Intern() when assigning string in routing data structures like ParameterDescriptor.Name and so on.
Some finalizing of routing initialization where TrimExcess will be called on routing collections.
Probably some nonstandard initial capacity for some routing collections.

Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-mvcIncludes: MVC, Actions and Controllers, Localization, CORS, most templates

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions