Asp.net-Core

ASP.NET core 高記憶體消耗

  • March 22, 2022

我有一些 ASP.NET 核心項目,我正在尋找消耗的記憶體。我只是被它嚇壞了。不是那麼大的工程。我有幾個控制器,它消耗大約 350MB 的 Ram,這對於網路伺服器來說是一個很大的記憶體量。

我的問題是我能以某種方式減少它嗎?我的一個想法是給你結構而不是數據關係模型的模型,但這不會像我想要的那樣減少那個mutch。還有其他一些方法嗎,我都喜歡嘗試:)

最後一件事,我現在的 ASP.NET 核心是一個非常複雜的框架,這意味著我不會將它用於小型項目,這只是用於教育目的。最後一個問題:記憶體是大問題嗎?

我的項目截圖: 截圖 1

我更大的控制器:)

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();
   }
}    
}

感謝所有的答案。

任何框架對於新手來說都是複雜的。話雖如此,與完整的框架相比,.NETCore 的執行時間更輕、更精簡,因此對於小型項目來說更加可行。

當您說您的 API 消耗大量記憶體時,是真的嗎?你目前在做什麼基準測試?您是否在本地執行它並查看記憶體消耗?Debug如果是這樣,除了您的應用程式碼之外,還有更多的東西在執行,例如調試符號,它們會增加看似很小的應用程序的記憶體佔用。

如果您確實需要查找記憶體洩漏或高消耗(這是特定於您的情況的指標),請使用經過驗證的分析器,如ANTS Profiler

編輯查看 .NETCore 6.0 的記憶體管理和 GC

當 ASP.NET Core 應用程序啟動時,GC:

為初始堆段保留一些記憶體。載入執行時時送出一小部分記憶體。

前面的記憶體分配是出於性能原因而完成的。性能優勢來自連續記憶體中的堆段。

此外,GC 模式 Server GC(預設)或 Workstation GC 對應用程序的記憶體使用有很大影響。

工作集從 500 MB 下降到 70 MB。

GC 每秒執行多次第 0 代收集,而不是每兩秒。

GC 從 300 MB 下降到 10 MB。

在大多數情況下,Server GC 是理想的選擇。但是,對於不期望太多流量的小型應用程序,則應考慮使用 GC 模式。

雖然看起來一個基本的應用程序會消耗大量記憶體,但重要的是,當應用程序啟動時,GC 會抓取一塊連續的記憶體。

這意味著一旦您的應用程序啟動,就已經為您的使用者對象保留了記憶體,並且執行時不需要從作業系統請求更多。如果應用程序不洩漏記憶體,記憶體使用量將在分配和收集對象時保持穩定。

引用自:https://stackoverflow.com/questions/49371025