.net memória não é recuperada

9

Eu tenho um 'serviço' (owin / webapi + odp.net gerenciado) que é executado com o 'modo gc do servidor' na máquina x64. Após a execução, o uso de memória do conjunto de testes ficou em torno de 2 Gb. Eu 'gerava' pressão de memória naquela máquina (outro programa que consumia toda a memória disponível e mais). Eu estava esperando que as janelas forçassem o .net a liberar alguma memória. No entanto, isso não aconteceu. Aqui está uma saída do windbg:

0:018> !dumpheap -stat
Statistics:
              MT    Count    TotalSize Class Name
00007ffd10445b90        1           24 System.Collections.Generic.GenericEqualityComparer'1[[System.UInt64, mscorlib]]
...
00007ffd0f904918   100864     11616976 System.Object[]
0000005b19face20       84   1810674044      Free
Total 720544 objects
Fragmented blocks larger than 0.5 MB:
            Addr     Size      Followed by
0000005b1c3c8800  425.6MB 0000005b36d56c50 System.Func'2[[System.IAsyncResult, mscorlib],[System.Net.HttpListenerContext, System]]
0000005c1c3fcf00   28.2MB 0000005c1e02be58 System.Reflection.Emit.MethodBuilder
0000005c1e02e5b0  268.0MB 0000005c2ec313d8 System.Threading.OverlappedData
0000005c2ec31678  142.3MB 0000005c37a830a0 System.Func'2[[System.IAsyncResult, mscorlib],[System.Net.HttpListenerContext, System]]
0000005d1c541aa0  404.8MB 0000005d35a1a958 System.Func'2[[System.IAsyncResult, mscorlib],[System.Net.HttpListenerContext, System]]
0000005d35a1e5a8    3.8MB 0000005d35df0c40 System.Func'2[[System.IAsyncResult, mscorlib],[System.Net.HttpListenerContext, System]]
0000005e1cfe7128  444.1MB 0000005e38c0c3f0 System.Byte[]
0000005e38c8cfb8    4.5MB 0000005e39110988 System.Byte[]
0000005e39111bf8    1.2MB 0000005e3923a570 System.Byte[]
0000005e3923b7e0    0.7MB 0000005e392ed7d0 System.Byte[]
0000005e392eea40    1.1MB 0000005e39401910 System.Byte[]

0:018> !heapstat
Heap             Gen0         Gen1         Gen2          LOH
Heap0       455256040           24           24      3713672
Heap1       464550872           24      4327776       727456
Heap2       428541352     10344768        12616           24
Heap3       474250128           24     21350456           24
Total      1822598392     10344840     25690872      4441176

Free space:                                                 Percentage
Heap0       446429064            0            0      1819552SOH: 98% LOH: 48%
Heap1       459823968            0          144          152SOH: 98% LOH:  0%
Heap2       428520936        34904           24           24SOH: 97% LOH:100%
Heap3       474044952            0          336           24SOH: 95% LOH:100%
Total      1808818920        34904          504      1819752

Portanto, há apenas cerca de 48Mb realmente usados e 1.8Gb livres, a maior parte da memória não está no LOH, mas no heap Gen 0, mas o .net não retorna essa memória. E enquanto isso o sistema estava faminto por memória. Por exemplo, o IIS falhou ao iniciar porque não havia memória suficiente.

Por que a memória não foi recuperada pelo Windows?

    
por koruyucu 10.08.2015 в 14:44
fonte

2 respostas

2

Bem janelas não podem "forçar" .Net para liberar memória. Embora eu não seja um expert em runtime do .Net, minha experiência tem sido que o framework .net irá prender a memória assim que seu aplicativo começar a consumir muito dele. Ele vai devagar, devolver o que é visível. Do ponto de vista do Windows, ele realmente não sabe o que o .Net fará com ele, mas o .Net reivindicou que a memória do sistema operacional e até ele (.net) devolve as janelas não pode dar essa memória para outro aplicativo. Existem vários blocos de 400 + mb de System.Byte [] que estão sendo mantidos, o que pode ser indicativo de um vazamento de memória. Do ponto de vista do sistema operacional, o Framework solicitou a memória e até usou essa memória até que seja explicitamente (a partir do framework não você) que as janelas anteriores não possam fazer nada a respeito. Eu iria perfil de seu aplicativo com muito cuidado, porque geralmente o motivo. Net não está liberando memória é porque você tem um vazamento de memória. Usar as ferramentas de análise de memória no Visual Studio deve mostrar se você está deixando a memória "Fixada" ou apenas aferrando-se a ela. Culpados realmente ruins são frequentemente variáveis / eventos de classe estática.

SO link: . NET Uso de memória livre (como evitar a sobrecarga / liberação de memória para o sistema operacional)

    
por Nathan 01.09.2015 / 05:40
fonte
0

Desde então, o Windows não pode compelir o aplicativo a liberar objetos.Você precisa encontrar uma maneira de definir o uso máximo de memória para o aplicativo & amp; quando o limite máximo for atingido, chame o coletor de lixo manualmente via GC.Collect ().

Enquanto o aplicativo estiver em execução, tente obter o Process & amp; defina o maxLimit, semelhante a this

    
por Nikita Shrivastava 01.09.2015 / 08:37
fonte