madskristensen / BundlerMinifier

Visual Studio extension
Other
611 stars 171 forks source link

Memory leak because BundleProvider.Dispose is not called in TagHelpers project #562

Open mrdnote opened 3 years ago

mrdnote commented 3 years ago

A memory leak is caused because a BundleProvider instance is created many times but never disposed:

BundlerMinifier.TagHelpers.BundleTagHelper.cs:

_bundleProvider = bundleProvider ?? new BundleProvider(hostingEnvironment);

(bundleProvider is always null here)

The file watcher that is created in the constructor of the BundleProvider is therefore never disposed. Can you imagine what happens if you have a few bundle tags on your page? My webapp crashes every other day because it reaches 100% memory because of this bug.

I guess the problem boils down to the fact that the bundleProvider parameter is not injected into the ctor of BundleTagHelper here:

BundlerMinifier.TagHelpers.BundleTagHelper.cs:

public BundleTagHelper(IWebHostEnvironment hostingEnvironment, IMemoryCache cache, HtmlEncoder htmlEncoder, 
    IUrlHelperFactory urlHelperFactory, BundleOptions options = null, IBundleProvider bundleProvider = null)
mrdnote commented 3 years ago

So the workaround is easy, just call AddBundles() in your startup class:

    public void ConfigureServices(IServiceCollection services)
    {
        // Code deleted for clarity

        services.AddBundles();

This will cause the bundle provider to be registered with IoC container and from then on passed in the ctor of BundleTagHelper and consequently only created once (a singleton).

The need for the AddBundles() call isn't documented, and also, I'd rather have you throwing an error in the case AddBundles is not called instead of eating up memory.