Sunucu tarafı Blazor uygulamaları barındırma ve dağıtma

Not

Bu, bu makalenin en son sürümü değildir. Geçerli sürüm için bu makalenin .NET 8 sürümüne bakın.

Uyarı

ASP.NET Core'un bu sürümü artık desteklenmiyor. Daha fazla bilgi için bkz . .NET ve .NET Core Destek İlkesi. Geçerli sürüm için bu makalenin .NET 8 sürümüne bakın.

Önemli

Bu bilgiler, ticari olarak piyasaya sürülmeden önce önemli ölçüde değiştirilebilen bir yayın öncesi ürünle ilgilidir. Burada verilen bilgilerle ilgili olarak Microsoft açık veya zımni hiçbir garanti vermez.

Geçerli sürüm için bu makalenin .NET 8 sürümüne bakın.

Bu makalede, ASP.NET Core kullanarak sunucu tarafı Blazor uygulamaları (Blazor Web Apps ve uygulamalar) barındırma ve Blazor Server dağıtma işlemleri açıklanmaktadır.

Konak yapılandırma değerleri

Sunucu tarafı Blazor uygulamalar Genel Ana Bilgisayar yapılandırma değerlerini kabul edebilir.

Dağıtım

Sunucu tarafı barındırma modeli kullanılarak, Blazor ASP.NET Core uygulamasının içinden sunucuda yürütülür. Kullanıcı arabirimi güncelleştirmeleri, olay işleme ve JavaScript çağrıları bir SignalR bağlantı üzerinden işlenir.

ASP.NET Core uygulaması barındırabilen bir web sunucusu gereklidir. Visual Studio sunucu tarafı uygulama proje şablonu içerir. Proje şablonları hakkında Blazor daha fazla bilgi için bkz . ASP.NET Core Blazor proje yapısı.

Bir uygulamayı Yayın yapılandırması'nda yayımlayın ve yer tutucunun bin/Release/{TARGET FRAMEWORK}/publish hedef çerçeve olduğu {TARGET FRAMEWORK} klasörün içeriğini dağıtın.

Ölçeklenebilirlik

Tek bir sunucunun ölçeklenebilirliğini göz önünde bulundurarak (ölçeği artırdığınızda), bir uygulamanın kullanabileceği bellek büyük olasılıkla kullanıcı talebi arttıkça uygulamanın tükettiği ilk kaynaktır. Sunucudaki kullanılabilir bellek aşağıdakileri etkiler:

  • Bir sunucunun destekleyebilecek etkin devre sayısı.
  • İstemcide kullanıcı arabirimi gecikme süresi.

Güvenli ve ölçeklenebilir sunucu tarafı Blazor uygulamaları oluşturma yönergeleri için aşağıdaki kaynaklara bakın:

Her bağlantı hattı, en az Merhaba Dünya stilindeki bir uygulama için yaklaşık 250 KB bellek kullanır. Bir bağlantı hattının boyutu, uygulamanın koduna ve her bileşenle ilişkili durum bakım gereksinimlerine bağlıdır. Uygulamanız ve altyapınız için geliştirme sırasında kaynak taleplerini ölçmenizi öneririz, ancak aşağıdaki temel dağıtım hedefinizi planlamada bir başlangıç noktası olabilir: Uygulamanızın 5.000 eşzamanlı kullanıcıyı desteklemesini bekliyorsanız, uygulamaya en az 1,3 GB sunucu belleği (veya kullanıcı başına yaklaşık 273 KB) bütçelendirmeyi göz önünde bulundurun.

SignalR yapılandırması

SignalR'nin barındırma ve ölçeklendirme koşulları kullanan SignalRuygulamalar için Blazor geçerlidir.

Yapılandırma yönergeleri de dahil olmak üzere uygulamalar hakkında SignalR daha fazla bilgi için bkz. ASP.NET Çekirdek BlazorSignalR kılavuzu.Blazor

Taşımalar

Blazordaha düşük gecikme süresi, daha iyi güvenilirlik ve gelişmiş güvenlik nedeniyle aktarım olarak SignalR WebSockets kullanırken en iyi sonucu verir. Uzun Yoklama , WebSockets kullanılamadığında veya uygulama Uzun Yoklama kullanacak şekilde açıkça yapılandırıldığında tarafından SignalR kullanılır.

Uzun Yoklama kullanılıyorsa bir konsol uyarısı görüntülenir:

Uzun Yoklama geri dönüş aktarımı kullanılarak WebSockets aracılığıyla bağlanılamadı. Bunun nedeni, bağlantıyı engelleyen bir VPN veya ara sunucu olabilir.

Genel dağıtım ve bağlantı hataları

Coğrafi veri merkezlerine genel dağıtım önerileri:

  • Uygulamayı kullanıcıların çoğunun bulunduğu bölgelere dağıtın.
  • Kıtalar arasındaki trafik için artan gecikme süresini dikkate alın. Yeniden bağlantı kullanıcı arabiriminin görünümünü denetlemek için bkz . ASP.NET Çekirdek BlazorSignalR kılavuzu.
  • Azure SignalR Hizmeti'ni kullanmayı göz önünde bulundurun.

Azure App Service

Azure Uygulaması Hizmetinde barındırmak için WebSockets ve Uygulama İsteği Yönlendirmesi (ARR) benşimi olarak da adlandırılan oturum benzimliği için yapılandırma gerekir.

Not

Blazor Azure Uygulaması Hizmeti'ne yönelik bir uygulama Için Azure SignalR Hizmeti gerekmez.

Uygulamanın Azure Uygulaması Hizmeti'ne kaydı için aşağıdakileri etkinleştirin:

  • WebSockets aktarımının çalışmasına izin vermek için WebSockets. Varsayılan ayar Kapalı'dır.
  • Bir kullanıcıdan gelen istekleri aynı App Service örneğine yönlendirmek için oturum benzimi. Varsayılan ayar Açık'tır.
  1. Azure portalında App Services'da web uygulamasına gidin.
  2. Ayarlar Yapılandırması'nı> açın.
  3. Web yuvalarını Açık olarak ayarlayın.
  4. Oturum benzitesi'nin Açık olarak ayarlandığını doğrulayın.

Azure SignalR Hizmeti

İsteğe bağlı Azure SignalR Hizmeti , bir sunucu tarafı uygulamasını SignalR çok sayıda eşzamanlı bağlantıya ölçeklendirmek için uygulamanın hub'ı ile birlikte çalışır. Buna ek olarak, hizmetin küresel erişim ve yüksek performanslı veri merkezleri coğrafya nedeniyle gecikme süresini azaltmaya önemli ölçüde yardımcı olur.

Hizmet, Azure Uygulaması Hizmetinde veya Azure Container Apps'te barındırılan uygulamalar için Blazor gerekli değildir, ancak diğer barındırma ortamlarında yararlı olabilir:

  • Bağlantı ölçeğini genişletmeyi kolaylaştırmak için.
  • Genel dağıtımı işleme.

Not

Durum bilgisi olan yeniden bağlantı (WithStatefulReconnect), .NET 8 ile yayımlandı ancak şu anda Azure SignalR Hizmeti için desteklenmiyor. Daha fazla bilgi için bkz . Durum Bilgisi Olan Yeniden Bağlanma Desteği? (Azure/azure-signalr #1878).

Uygulamanın Uzun Yoklama kullanması veya WebSockets yerine Uzun Yoklama'ya geri dönmesi durumunda, Azure SignalR Hizmeti'nde Uzun Yoklama bağlantıları için izin verilen en yüksek yoklama aralığını tanımlayan maksimum yoklama aralığını (MaxPollIntervalInSecondsvarsayılan: 5 saniye, sınır: 1-300 saniye) yapılandırmanız gerekebilir. Sonraki yoklama isteği en yüksek yoklama aralığı içinde gelmezse, hizmet istemci bağlantısını kapatır.

Hizmeti üretim dağıtımına bağımlılık olarak ekleme hakkında yönergeler için bkz. ASP.NET Core SignalR uygulamasını Azure Uygulaması Hizmeti'ne yayımlama.

Daha fazla bilgi için bkz.

Azure Container Apps

Azure Container Apps hizmetinde sunucu tarafı Blazor uygulamaları ölçeklendirme hakkında daha ayrıntılı bilgi için bkz . Azure'da ASP.NET Core Apps'i ölçeklendirme. Öğreticide, Azure Container Apps'te uygulamaları barındırmak için gereken hizmetleri oluşturma ve tümleştirme açıklanmaktadır. Bu bölümde temel adımlar da sağlanmıştır.

  1. Azure Container Apps'te Oturum Benşimi (Azure belgeleri) yönergelerini izleyerek Azure Container Apps hizmetini oturum benşimi için yapılandırın.

  2. ASP.NET Core Data Protection (DP) hizmeti, anahtarları tüm kapsayıcı örneklerinin erişebileceği merkezi bir konumda kalıcı hale getirmek için yapılandırılmalıdır. Anahtarlar Azure Blob Depolama depolanabilir ve Azure Key Vault ile korunabilir. DP hizmeti, bileşenleri seri durumdan Razor çıkarmak için anahtarları kullanır. DP hizmetini Azure Blob Depolama ve Azure Key Vault kullanacak şekilde yapılandırmak için aşağıdaki NuGet paketlerine başvurun:

    Not

    .NET uygulamalarına paket ekleme hakkında yönergeler için, Paket tüketimi iş akışında (NuGet belgeleri) paketleri yüklemek ve yönetmek altındaki makalelere bakın. NuGet.org'da doğru paket sürümlerini onaylayın.

  3. Aşağıdaki vurgulanmış kodla güncelleştirin Program.cs :

    using Azure.Identity;
    using Microsoft.AspNetCore.DataProtection;
    using Microsoft.Extensions.Azure;
    
    var builder = WebApplication.CreateBuilder(args);
    var BlobStorageUri = builder.Configuration["AzureURIs:BlobStorage"];
    var KeyVaultURI = builder.Configuration["AzureURIs:KeyVault"];
    
    builder.Services.AddRazorPages();
    builder.Services.AddHttpClient();
    builder.Services.AddServerSideBlazor();
    
    builder.Services.AddAzureClientsCore();
    
    builder.Services.AddDataProtection()
                    .PersistKeysToAzureBlobStorage(new Uri(BlobStorageUri),
                                                    new DefaultAzureCredential())
                    .ProtectKeysWithAzureKeyVault(new Uri(KeyVaultURI),
                                                    new DefaultAzureCredential());
    var app = builder.Build();
    
    if (!app.Environment.IsDevelopment())
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }
    
    app.UseHttpsRedirection();
    app.UseStaticFiles();
    
    app.UseRouting();
    
    app.UseAuthorization();
    
    app.MapRazorPages();
    
    app.Run();
    

    Yukarıdaki değişiklikler, uygulamanın merkezi, ölçeklenebilir bir mimari kullanarak DP hizmetini yönetmesine olanak sağlar. DefaultAzureCredential kod Azure'a dağıtıldıktan sonra yönetilen identity kapsayıcı uygulamasını bulur ve blob depolamaya ve uygulamanın anahtar kasasına bağlanmak için bunu kullanır.

  4. Yönetilen identity kapsayıcı uygulamasını oluşturmak ve blob depolamaya ve anahtar kasasına erişim vermek için aşağıdaki adımları tamamlayın:

    1. Azure Portal'da kapsayıcı uygulamasının genel bakış sayfasına gidin.
    2. Sol gezinti bölmesinden Hizmet Bağlayıcısı'nı seçin.
    3. Üst gezinti bölmesinden + Oluştur'u seçin.
    4. Bağlantı oluştur açılır menüsünde aşağıdaki değerleri girin:
      • Kapsayıcı: Uygulamanızı barındırmak için oluşturduğunuz kapsayıcı uygulamasını seçin.
      • Hizmet türü: Blob Depolama'yı seçin.
      • Abonelik: Kapsayıcı uygulamasının sahibi olan aboneliği seçin.
      • Bağlantı adı: adını scalablerazorstoragegirin.
      • İstemci türü: .NET'i ve ardından İleri'yi seçin.
    5. Sistem tarafından atanan yönetilen'i identity ve ardından İleri'yi seçin.
    6. Varsayılan ağ ayarlarını kullanın ve İleri'yi seçin.
    7. Azure ayarları doğruladıktan sonra Oluştur'u seçin.

    Anahtar kasası için önceki ayarları yineleyin. Temel Bilgiler sekmesinde uygun anahtar kasası hizmetini ve anahtarını seçin.

IIS

IIS kullanırken şunları etkinleştirin:

Daha fazla bilgi için bkz. Iis'de ASP.NET Core uygulaması yayımlama konusunda yönergeler ve dış IIS kaynak çapraz bağlantıları.

Kubernetes

Oturum benzimi için aşağıdaki Kubernetes ek açıklamalarıyla giriş tanımı oluşturun:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: <ingress-name>
  annotations:
    nginx.ingress.kubernetes.io/affinity: "cookie"
    nginx.ingress.kubernetes.io/session-cookie-name: "affinity"
    nginx.ingress.kubernetes.io/session-cookie-expires: "14400"
    nginx.ingress.kubernetes.io/session-cookie-max-age: "14400"

Nginx ile Linux

Aşağıdaki değişikliklerle ASP.NET Core SignalR uygulamasının yönergelerini izleyin:

Daha fazla bilgi ve yapılandırma kılavuzu için aşağıdaki kaynaklara bakın:

Apache ile Linux

Linux üzerinde Apache'nin arkasında bir Blazor uygulama barındırmak için HTTP ve WebSockets trafiği için yapılandırın ProxyPass .

Aşağıdaki örnekte:

  • Kestrel sunucusu konak makinede çalışıyor.
  • Uygulama, 5000 numaralı bağlantı noktasındaki trafiği dinler.
ProxyPreserveHost   On
ProxyPassMatch      ^/_blazor/(.*) http://localhost:5000/_blazor/$1
ProxyPass           /_blazor ws://localhost:5000/_blazor
ProxyPass           / http://localhost:5000/
ProxyPassReverse    / http://localhost:5000/

Aşağıdaki modülleri etkinleştirin:

a2enmod   proxy
a2enmod   proxy_wstunnel

WebSockets hataları için tarayıcı konsolunu denetleyin. Örnek hatalar:

  • Firefox şu konumdan sunucuyla bağlantı kuramıyor: ws://the-domain-name.tld/_blazor?id=XXX
  • Hata: 'WebSockets' aktarımı başlatılamadı: Hata: Aktarımda bir hata oluştu.
  • Hata: 'LongPolling' aktarımı başlatılamadı: TypeError: this.transport undefined
  • Hata: Kullanılabilir aktarımlardan herhangi biriyle sunucuya bağlanılamıyor. WebSockets başarısız oldu
  • Hata: Bağlantı 'Bağlı' Durumunda değilse veri gönderilemez.

Daha fazla bilgi ve yapılandırma kılavuzu için aşağıdaki kaynaklara bakın:

Ağ gecikme süresini ölçme

JS birlikte çalışma , aşağıdaki örnekte gösterildiği gibi ağ gecikme süresini ölçmek için kullanılabilir.

MeasureLatency.razor:

@inject IJSRuntime JS

<h2>Measure Latency</h2>

@if (latency is null)
{
    <span>Calculating...</span>
}
else
{
    <span>@(latency.Value.TotalMilliseconds)ms</span>
}

@code {
    private DateTime startTime;
    private TimeSpan? latency;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            startTime = DateTime.UtcNow;
            var _ = await JS.InvokeAsync<string>("toString");
            latency = DateTime.UtcNow - startTime;
            StateHasChanged();
        }
    }
}
@inject IJSRuntime JS

<h2>Measure Latency</h2>

@if (latency is null)
{
    <span>Calculating...</span>
}
else
{
    <span>@(latency.Value.TotalMilliseconds)ms</span>
}

@code {
    private DateTime startTime;
    private TimeSpan? latency;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            startTime = DateTime.UtcNow;
            var _ = await JS.InvokeAsync<string>("toString");
            latency = DateTime.UtcNow - startTime;
            StateHasChanged();
        }
    }
}
@inject IJSRuntime JS

<h2>Measure Latency</h2>

@if (latency is null)
{
    <span>Calculating...</span>
}
else
{
    <span>@(latency.Value.TotalMilliseconds)ms</span>
}

@code {
    private DateTime startTime;
    private TimeSpan? latency;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            startTime = DateTime.UtcNow;
            var _ = await JS.InvokeAsync<string>("toString");
            latency = DateTime.UtcNow - startTime;
            StateHasChanged();
        }
    }
}
@inject IJSRuntime JS

<h2>Measure Latency</h2>

@if (latency is null)
{
    <span>Calculating...</span>
}
else
{
    <span>@(latency.Value.TotalMilliseconds)ms</span>
}

@code {
    private DateTime startTime;
    private TimeSpan? latency;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            startTime = DateTime.UtcNow;
            var _ = await JS.InvokeAsync<string>("toString");
            latency = DateTime.UtcNow - startTime;
            StateHasChanged();
        }
    }
}
@inject IJSRuntime JS

@if (latency is null)
{
    <span>Calculating...</span>
}
else
{
    <span>@(latency.Value.TotalMilliseconds)ms</span>
}

@code {
    private DateTime startTime;
    private TimeSpan? latency;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            startTime = DateTime.UtcNow;
            var _ = await JS.InvokeAsync<string>("toString");
            latency = DateTime.UtcNow - startTime;
            StateHasChanged();
        }
    }
}

Makul bir kullanıcı arabirimi deneyimi için 250 ms veya daha kısa süreli bir kullanıcı arabirimi gecikme süresi öneririz.

Bellek yönetimi

Sunucuda, her kullanıcı oturumu için yeni bir bağlantı hattı oluşturulur. Her kullanıcı oturumu, tarayıcıda tek bir belgenin işlenmesine karşılık gelir. Örneğin, birden çok sekme birden çok oturum oluşturur.

Blazor, oturumu başlatan bağlantı hattı olarak adlandırılan tarayıcıya sabit bir bağlantı tutar. Bağlantılar, kullanıcının ağ bağlantısını kaybetmesi veya aniden tarayıcıyı kapatması gibi çeşitli nedenlerden herhangi biri nedeniyle herhangi bir zamanda kaybolabilir. Bağlantı kesildiğinde, Blazor "bağlantısı kesilmiş" bir havuza sınırlı sayıda bağlantı hattı yerleştiren ve istemcilere oturumu yeniden bağlamak ve yeniden kurmak için sınırlı süre veren bir kurtarma mekanizması vardır (varsayılan: 3 dakika).

Bu süreden sonra devreyi Blazor serbest bırakır ve oturumu atar. Bu noktadan sonra bağlantı hattı çöp toplama (GC) için uygundur ve devrenin GC nesli için bir toplama tetiklendiğinde talep edilir. Anlaşılması gereken önemli bir yön, devrelerin uzun bir ömrü olmasıdır, yani bağlantı hattı tarafından köklenen nesnelerin çoğu sonunda 2. Nesil'e ulaşır. Sonuç olarak, 2. Nesil koleksiyonu gerçekleşene kadar bu nesnelerin yayınlanmasını göremeyebilirsiniz.

Genel olarak bellek kullanımını ölçme

Ön koşullar:

  • Uygulamanın Yayın yapılandırmasında yayımlanması gerekir. Oluşturulan kod üretim dağıtımı için kullanılan kodu temsil etmediğinden hata ayıklama yapılandırma ölçümleri ilgili değildir.
  • Uygulamanın davranışını da etkileyebileceği ve sonuçları bozabileceği için uygulamanın bir hata ayıklayıcısı eklenmeden çalışması gerekir. Visual Studio'da, menü çubuğundan Hata Ayıklama>Olmadan Başlat'ı veya klavyeyi kullanarak Ctrl+F5'i seçerek uygulamayı hata ayıklamadan başlatın.
  • .NET tarafından gerçekte ne kadar bellek kullanıldığını anlamak için farklı bellek türlerini göz önünde bulundurun. Geliştiriciler genellikle kullanımdaki gerçek belleğin üst sınırı olan Windows işletim sistemindeki Görev Yöneticisi'nde uygulama belleği kullanımını inceler. Daha fazla bilgi için aşağıdaki makalelere bakın:

Uygulanan bellek kullanımı Blazor

Tarafından blazor kullanılan belleği aşağıdaki gibi hesaplıyoruz:

(Etkin Devreler × Bağlantı Hattı Başına Bellek) + (Bağlantı Kesilen Devreler × Devre Başına Bellek)

Bir bağlantı hattının kullandığı bellek miktarı ve bir uygulamanın koruyabileceği maksimum etkin bağlantı hattı büyük ölçüde uygulamanın nasıl yazıldığını bağlıdır. Olası aktif devrelerin maksimum sayısı kabaca şu şekilde açıklanmıştır:

Maksimum Kullanılabilir Bağlantı / Hattı Başına Bellek Maksimum = Olası Etkin Devre sayısı

içinde bellek sızıntısı olması Blazoriçin aşağıdakilerin doğru olması gerekir:

  • Bellek uygulama tarafından değil çerçeve tarafından ayrılmalıdır. Uygulamada 1 GB'lık bir dizi ayırırsanız, uygulamanın dizinin atılması işlemini yönetmesi gerekir.
  • Bellek etkin olarak kullanılmamalıdır; başka bir deyişle devre etkin değildir ve bağlantısı kesilmiş devreler önbelleğinden çıkarılmıştır. En fazla etkin devre çalışıyorsa, belleğin bitmesi bellek sızıntısı değil ölçek sorunudur.
  • Bağlantı hattının GC oluşturma işlemi için bir çöp toplama (GC) çalıştırıldı, ancak çerçevedeki başka bir nesne bağlantı hattına güçlü bir başvuru içerdiğinden çöp toplayıcı devreyi talep etmedi.

Diğer durumlarda bellek sızıntısı olmaz. Devre etkinse (bağlı veya bağlantısı kesilmişse), devre hala kullanımdadır.

Bağlantı hattının GC oluşturması için bir koleksiyon çalışmazsa, atık toplayıcının o anda belleği boşaltması gerekmeyen bellek serbest bırakılmaz.

GC oluşturma için bir koleksiyon çalıştırılırsa ve bağlantı hattını serbest bırakırsa, .NET sanal belleği etkin tutmaya karar verebileceği için belleği işleme değil GC istatistiklerine göre doğrulamanız gerekir.

Bellek serbest değilse, etkin olmayan veya bağlantısı kesilmeyen ve kökünü çerçevedeki başka bir nesnenin oluşturduğu bir bağlantı hattı bulmanız gerekir. Başka bir durumda, bellek yetersizliği geliştirici kodunda bir uygulama sorunudur.

Bellek kullanımını azaltma

Bir uygulamanın bellek kullanımını azaltmak için aşağıdaki stratejilerden herhangi birini benimseyin:

  • .NET işlemi tarafından kullanılan toplam bellek miktarını sınırlayın. Daha fazla bilgi için bkz . Atık toplama için çalışma zamanı yapılandırma seçenekleri.
  • Bağlantısı kesilmiş devre sayısını azaltın.
  • Bağlantı hattının bağlantısı kesilmiş durumda olmasına izin verilen süreyi azaltın.
  • Kapalı kalma sürelerinde toplama gerçekleştirmek için çöp toplamayı el ile tetikleyin.
  • Çöp toplamayı Sunucu modu yerine çöp toplamayı agresif bir şekilde tetikleyen İş İstasyonu modunda yapılandırın.

Bazı mobil cihaz tarayıcıları için yığın boyutu

İstemcide çalışan ve mobil cihaz tarayıcılarını, özellikle iOS'ta Safari'yi hedefleyen bir Blazor uygulama oluştururken, MSBuild özelliğine EmccMaximumHeapSize sahip uygulama için en yüksek belleği azaltmak gerekebilir. Daha fazla bilgi için bkz . ASP.NET Core'u Blazor WebAssemblybarındırma ve dağıtma.

Ek eylemler ve dikkat edilmesi gerekenler

  • Bellek talepleri yüksek olduğunda işlemin bellek dökümünü yakalayın ve nesnelerin en çok belleği aldığını ve bu nesnelerin nerede köke sahip olduğunu (bunlara başvuruyu barındıran nesneler) belirleyin.
  • kullanarak uygulamanızdaki belleğin nasıl davrandığını dotnet-countersgösteren istatistikleri inceleyebilirsiniz. Daha fazla bilgi için bkz. Performans sayaçlarını araştırma (dotnet-counters).
  • Gc tetiklendiğinde bile yakın gelecekte belleği yeniden kullanacağı için .NET belleği işletim sistemine hemen döndürmek yerine bellekte tutar. Bu, belleğin sürekli olarak işlenmesini ve ayrıştırılmasını önler ve bu da pahalıdır. GC'lerin gerçekleştiğini ve kullanılan bellek miktarının 0'a (sıfır) indiğini ancak .NET'in yeniden kullanmak için bellekte tuttuğunun işareti olan çalışma kümesi sayacının azaldığını görmediğiniz için bunu kullanırsanız dotnet-counters bu yansıtılır. Bu davranışı denetlemeye yönelik proje dosyası (.csproj) ayarları hakkında daha fazla bilgi için bkz . Atık toplama için çalışma zamanı yapılandırma seçenekleri.
  • Sunucu GC, uygulamanızı dondurmaktan kaçınmak için bunun kesinlikle gerekli olduğunu belirleyene kadar çöp toplamaları tetiklemez ve uygulamanızın makinede çalışan tek şey olduğunu göz önünde bulundurarak sistemdeki tüm belleği kullanabilmesini sağlar. Sistemde 50 GB varsa, atık toplayıcı 2. Nesil koleksiyonunu tetiklemeden önce 50 GB kullanılabilir belleğin tamamını kullanmayı arar.
  • Bağlantısı kesilmiş devre saklama yapılandırması hakkında bilgi için bkz . ASP.NET Çekirdek BlazorSignalR kılavuzu.

Belleği ölçme

  • Uygulamayı Yayın yapılandırması'nda yayımlayın.
  • Uygulamanın yayımlanmış bir sürümünü çalıştırın.
  • Çalışan uygulamaya hata ayıklayıcı eklemeyin.
  • 2. Nesil zorlamalı, sıkıştırmalı koleksiyonu tetikleme (GC.Collect(2, GCCollectionMode.Aggressive | GCCollectionMode.Forced, blocking: true, compacting: true)) bellek boşaltılıyor mu?
  • Uygulamanızın nesneleri büyük nesne yığınına ayırdığını düşünün.
  • Uygulama istekler ve işleme ile ısındıktan sonra bellek artışını test ediyor musunuz? Genellikle, kod ilk kez yürütülürken uygulamanın ayak izine sabit miktarda bellek ekleyen önbellekler vardır.