Tag: csharp, dotnet, clr, aspnetcore, efcore, memory-management
Livello: intermedio
TL;DR: Runtime CLR, gestione memoria con Garbage Collector (generazioni 0, 1, 2 e LOH), pattern async/await su ThreadPool e architettura ASP.NET Core con Dependency Injection nativa.
Common Language Runtime (CLR) gestisce esecuzione, JIT compilation, garbage collection e sicurezza dei tipi.
Common Type System (CTS) definisce i tipi supportati; Common Language Specification (CLS) garantisce interoperabilità tra linguaggi.
Value types allocati sullo stack o inline negli oggetti; Reference types allocati su managed heap.
Garbage Collector a tre generazioni (Gen 0, Gen 1, Gen 2) più Large Object Heap (LOH per oggetti >= 85.000 byte).
Pattern async/await non blocca thread; rilascia thread al ThreadPool durante operazioni di I/O asincrone.
Dependency Injection nativa con tre cicli di vita: Transient (nuova istanza sempre), Scoped (per richiesta HTTP), Singleton (unica istanza).
Middleware pipeline in ASP.NET Core gestisce request e response in ordine sequenziale bidirezionale.
Entity Framework Core supporta tracking query e as-no-tracking per ottimizzare letture in sola consultazione.
IDisposable e statement using rilasciano risorse unmanaged (handle SO, connessioni DB, socket) in modo deterministico.
Kestrel funge da web server HTTP cross-platform ad alte prestazioni predefinito per ASP.NET Core.
Q: Qual è la differenza tra string e StringBuilder?R: string è immutabile e ogni concatenazione alloca un nuovo oggetto sul managed heap. StringBuilder modifica un buffer interno mutabile, riducendo drasticamente le allocazioni e la pressione sul Garbage Collector in scenari di concatenazione intensiva.
Q: Quando si usa ValueTask<T> invece di Task<T>?R: Uso ValueTask<T> quando l'operazione asincrona si completa frequentemente in modo sincrono o da cache, evitando l'allocazione dell'oggetto Task sull'heap nel path sincrono ad alto throughput.
Q: Come funziona il Garbage Collector in .NET?R: Il GC è generazionale e mark-and-sweep: Gen 0 per oggetti a vita breve, Gen 1 come transizione, Gen 2 per lunga durata; scatta quando le soglie di memoria vengono superate per compattare e liberare l'heap.
Q: Che differenza c'è tra un servizio Scoped e uno Transient in ASP.NET Core?R: Un servizio Transient crea una nuova istanza ogni volta che viene richiesto dal container; uno Scoped crea una sola istanza per l'intero ciclo di vita di una singola richiesta HTTP.
Cattiva gestione delle connessioni: istanziare manualmente HttpClient invece di usare IHttpClientFactory causa socket exhaustion.
Blocco del thread asincrono con .Result o .Wait(), provocando thread pool starvation o deadlock.
Modifica concorrente di collezioni non thread-safe (come List<T> o Dictionary<TKey, TValue>) senza sync o classi concurrent.
Captive Dependency: iniettare un servizio Scoped dentro un Singleton estende la vita dello Scoped per tutta l'applicazione.
Mancata chiamata a Dispose() su stream o file handle non incapsulati in blocchi using.
N+1 query problem in EF Core per mancato utilizzo di eager loading con .Include().
# Comandi CLI frequenti
dotnet new webapi -n ApiService
dotnet build -c Release
dotnet run --project ApiService
dotnet test
dotnet add package Microsoft.EntityFrameworkCore
C#
// Registrazione lifecycle e middleware minimale
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddTransient<ITransientService, TransientService>();
builder.Services.AddScoped<IScopedService, ScopedService>();
builder.Services.AddSingleton<ISingletonService, SingletonService>();
var app = builder.Build();
app.Use(async (context, next) =>
{
// Esecuzione pre-elaborazione
await next();
// Esecuzione post-elaborazione
});
app.MapGet("/items/{id}", async (int id, IScopedService service) =>
{
var item = await service.GetByIdAsync(id);
return item is not null ? Results.Ok(item) : Results.NotFound();
});
app.Run();
[ ] Pattern di allocazione e frammentazione su Large Object Heap (LOH)
[ ] Implementazione e semantica del Dispose Pattern con GC.SuppressFinalize
[ ] Memory e Span per manipolazione dati ad alte prestazioni senza allocazioni
[ ] Differenze architetturali tra .NET Framework, .NET Core e .NET 8/9
[x] Cicli di vita dei servizi in ASP.NET Core Dependency Injection
[x] Utilizzo base di async, await e Task cancellation token