Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET core high memory consume

Tags:

asp.net-core

I have some ASP.NET core project and I was looking on memory that consumes. I just get terrified by it. It's not a that big project. I have a few controllers and it consumes about 350MB of Ram and that's a big amount of memory for the webserver.

My question is can I somehow reduce it? One idea that I have is to you struct instead of a model for Data Relation Model, but that will not reduce that that mutch as I want to. Are some other ways, I like to try them all :)

And the last thing, I now ASP.NET core is a very complex framework, that means I wont to use it for small Project this is just for education purposes. and last question: is the memory big problem?

Screenshot of my project: Screenshot 1

my bigger controller :)

using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using RustWiki.Data;
using RustWiki.Models.WikiViewModels;

namespace RustWiki.Controllers.api
{
[Produces("application/json")]
public class TableManagerController : Controller
{
    private readonly ApplicationDbContext _context;
    public TableManagerController(ApplicationDbContext context)
    {
        _context = context;
    }

    protected override void Dispose(bool disposing)
    {
        _context.Dispose();
        base.Dispose(disposing);
    }

    //Get
    [HttpGet]
    [Route("/api/ArmorTypes")]
    public IActionResult GetArmorTypes() => Ok(_context.ArmorTypes.ToList());

    [HttpGet]
    [Route("/api/Cloating")]
    public IActionResult GetCloating() => Ok(_context.Cloating.Include(c => c.ArmorType).Include(c => c.Defencis).Include(c => c.Item.ItemType).ToList());

    [HttpGet]
    [Route("/api/Defencis")]
    public IActionResult GetDefences() => Ok(_context.Defencis.ToList());

    [HttpGet]
    [Route("/api/Dmgs")]
    public IActionResult GetDmg() => Ok(_context.Dmgs.ToList());

    [HttpGet]
    [Route("/api/Equipment")]
    public IActionResult GetEquipment() => Ok(_context.Equipment.Include(e => e.Dmg).Include(e => e.Item.ItemType).ToList());

    [HttpGet]
    [Route("/api/Items")]
    public IActionResult GetItems() => Ok(_context.Items.Include(i => i.ItemType).ToList());

    [HttpGet]
    [Route("/api/ItemTypes")]
    public IActionResult GetItemType() => Ok(_context.ItemTypes.ToList());

    [HttpGet]
    [Route("/api/Resources")]
    public IActionResult GetResource() => Ok(_context.Resources.ToList());

    //Delete

    [HttpDelete]
    [Route("/api/ArmourTypes/{id}")]
    public IActionResult DelArmourType(int id) => Delete(_context.ArmorTypes, id);

    [HttpDelete]
    [Route("/api/Cloating/{id}")]
    public IActionResult DelCloating(int id) => Delete(_context.Cloating, id);

    [HttpDelete]
    [Route("/api/Defences/{id}")]
    public IActionResult DelDefencis(int id) => Delete(_context.Defencis, id);

    [HttpDelete]
    [Route("/api/Dmgs/{id}")]
    public IActionResult DelDmg(int id) => Delete(_context.Dmgs, id);

    [HttpDelete]
    [Route("/api/Equipments/{id}")]
    public IActionResult DelEquipment(int id) => Delete(_context.Equipment, id);

    [HttpDelete]
    [Route("/api/Items/{id}")]
    public IActionResult DelItem(int id) => Delete(_context.Items, id);

    [HttpDelete]
    [Route("/api/ItemTypes/{id}")]
    public IActionResult DelItemType(int id) => Delete(_context.ItemTypes, id);

    [HttpDelete]
    [Route("/api/Resources/{id}")]
    public IActionResult DelResource(int id) => Delete(_context.Resources, id);

    private IActionResult Delete<T>(DbSet<T> set, int id) where T : class
    {
        var obj = set.SingleOrDefault(delegate (T o)
        {
            return (o as IWikiModel)?.Id == id;
        });
        if (obj == null)
            return NotFound();
        set.Remove(obj);
        _context.SaveChanges();
        return Ok(obj);
    }

    //Create

    [HttpPost]
    [Route("/api/ArmourType")]
    public IActionResult CreateArmourType([FromBody]ArmorType type)
    {
        return Ok();
    }
}    
}

Thanks for all the answers.

like image 318
Pavel B. Avatar asked Mar 19 '18 19:03

Pavel B.


People also ask

How much memory does ASP.NET Core use?

The working set is constant at approximately 500 MB. CPU is 12%. The memory consumption and release (through GC) is stable.

Why .NET Core is high performance?

NET Core is faster for working with more modern libraries and programming languages. It is more lightweight and modular than . NET Framework, and you can use multiple versions of . NET in the same project.

How detect memory leak in .NET Core application?

Examine managed memory usage. Before you start collecting diagnostics data to help us root cause this scenario, you need to make sure you're actually seeing a memory leak (memory growth). You can use the dotnet-counters tool to confirm that. You can see that the managed heap memory is 4 MB right after startup.


1 Answers

Any framework will be complex to new starters. With that said, .NETCore is a much lighter and streamlined run-time compared to the full frameworks making it even more viable for small projects.

When you say that your API is consuming a lot of memory, is it really? What benchmarking are you currently doing? Are you running it locally and looking at memory consumption? If so, there are a lot more things running in Debug than just your application code like debug symbols that will increase the memory footprint of a seemingly small application.

If you do need to hunt down memory leaks or high consumption (this is a metric specific to your situation) then use a tried and tested profiler like ANTS Profiler.

EDIT: looking at memory management and GC for .NETCore 6.0

When an ASP.NET Core app starts, the GC:

Reserves some memory for the initial heap segments. Commits a small portion of memory when the runtime is loaded.

The preceding memory allocations are done for performance reasons. The performance benefit comes from heap segments in contiguous memory.

Furthermore, the GC mode Server GC (default) or Workstation GC has a large impact on the application's memory usage.

The working set drops from 500 MB to 70 MB.

The GC does generation 0 collections multiple times per second instead of every two seconds.

GC drops from 300 MB to 10 MB.

In most cases Server GC is the ideal option. However, for small app's not expecting much traffic then GC mode should be considered.

Although it may seem like a basic app is consuming a lot of memory, the important thing here is that the GC grabs a chunk of contiguous memory when the app starts.

Meaning once your app starts there is already reserved memory for your user objects and the run-time doesn't need to request more from the OS. Provided the app does not leak memory, memory usage would remain stable as objects are allocated and collected.

like image 53
ethane Avatar answered Sep 25 '22 08:09

ethane