<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.technet.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Supporto Tecnico Enterprise : NT Kernel Architecture</title><link>http://blogs.technet.com/itasupport/archive/tags/NT+Kernel+Architecture/default.aspx</link><description>Tags: NT Kernel Architecture</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Memoria Paged e NonPaged Pool – Come risolvere un memory leak</title><link>http://blogs.technet.com/itasupport/archive/2009/05/18/memoria-paged-e-nonpaged-pool-come-risolvere-un-memory-leak.aspx</link><pubDate>Mon, 18 May 2009 02:00:00 GMT</pubDate><guid isPermaLink="false">d5e57398-b9ef-4490-9955-07cbb4e4a80d:3239803</guid><dc:creator>itentblg</dc:creator><slash:comments>4</slash:comments><comments>http://blogs.technet.com/itasupport/comments/3239803.aspx</comments><wfw:commentRss>http://blogs.technet.com/itasupport/commentrss.aspx?PostID=3239803</wfw:commentRss><description>&lt;P&gt;In questo post vedremo come risolvere un leak di memoria e identificare il driver responsabile. &lt;BR&gt;Vi consiglio di leggere il post &lt;STRONG&gt;&lt;A href="http://blogs.technet.com/itasupport/archive/2009/05/11/memoria-paged-e-nonpaged-pool-come-identificare-un-memory-leak.aspx" target=_blank mce_href="http://blogs.technet.com/itasupport/archive/2009/05/11/memoria-paged-e-nonpaged-pool-come-identificare-un-memory-leak.aspx"&gt;Memoria Paged e NonPaged Pool – Come identificare un memory leak&lt;/A&gt;&lt;/STRONG&gt; per verificare che effettivamente siamo in presenza di un leak di memoria.&lt;/P&gt;
&lt;H3&gt;Utilizzare il PoolMon&lt;/H3&gt;
&lt;P&gt;L’allocazione di una quantità di byte in una delle memorie Pool utilizza un &lt;STRONG&gt;sistema di tagging&lt;/STRONG&gt;. Un TAG è un identificativo di quattro byte associato ad ogni porzione di memoria Pool allocata.&lt;/P&gt;
&lt;P&gt;Il TAG viene specificato da un driver, durante l’allocazione della memoria, attraverso la routine &lt;A href="http://msdn.microsoft.com/en-us/library/ms796989.aspx" mce_href="http://msdn.microsoft.com/en-us/library/ms796989.aspx"&gt;ExAllocatePoolWithTag&lt;/A&gt;. I seguenti tre parametri, devono essere specificati durante la chiamata a questa routine:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;PoolType&lt;/STRONG&gt;: Il tipo di memoria Pool da allocare (Paged o NonPaged) &lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;NumberofBytes&lt;/STRONG&gt;: Il numero di byte da allocare con la richiesta &lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;TAG&lt;/STRONG&gt;: il Pool TAG, rappresentato attraverso quattro caratteri ASCII &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;L’obiettivo dei Pool TAG è quello di fornire un meccanismo, che attraverso degli identificatore potenzialmente univoci, consenta di stabilire quali driver stanno allocando la memoria. Inoltre, durante la fase di sviluppo di un driver, i TAG sono utili per poter differenziare le diverse tipologie di allocazione, rendendo più selettiva un’eventuale investigazione attraverso il tool &lt;A href="http://support.microsoft.com/kb/244617" mce_href="http://support.microsoft.com/kb/244617"&gt;&lt;STRONG&gt;Driver Verifier&lt;/STRONG&gt;&lt;/A&gt;.&lt;/P&gt;
&lt;H3&gt;Identificare il TAG e byte allocati&lt;/H3&gt;
&lt;P&gt;Per poter verificare quanti byte sono allocati da un determinato TAG occorrerà utilizzare il tool &lt;B&gt;poolmon.exe&lt;/B&gt;, che è possibile recuperare dalla cartella \Support\Tools del CD d’installazione del Sistema Operativo.&lt;/P&gt;
&lt;P&gt;Questo tool consente di ottenere un report di tutti i TAG della Paged e Non Paged Pool con i relativi byte allocati. &lt;BR&gt;In Windows Server 2003 il Pool tagging è già abilitato, mentre in Windows Server 2000 e Windows XP è necessario abilitarlo attraverso il tool Gflags.exe presente sempre nella cartella \Support\Tools del supporto di installazione, o modificando le opportune chiavi di registro.&lt;/P&gt;
&lt;P&gt;Per maggiori informazioni sull'utilizzo di questo tool potete consultare l’articolo &lt;A href="http://support.microsoft.com/kb/177415" target=_blank mce_href="http://support.microsoft.com/kb/177415"&gt;How to use Memory Pool Monitor (Poolmon.exe) to troubleshoot kernel mode memory leaks&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;La seguente immagine illustra un esempio di output relativo al poolmon:&lt;/P&gt;
&lt;P align=center&gt;&lt;A href="http://blogs.technet.com/blogfiles/itasupport/WindowsLiveWriter/MemoriaPagedeNonPagedPoolComerisolvereun_EE09/image008_2.jpg" mce_href="http://blogs.technet.com/blogfiles/itasupport/WindowsLiveWriter/MemoriaPagedeNonPagedPoolComerisolvereun_EE09/image008_2.jpg"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: block; FLOAT: none; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; MARGIN-LEFT: auto; BORDER-LEFT-WIDTH: 0px; MARGIN-RIGHT: auto" title=image008 border=0 alt=image008 src="http://blogs.technet.com/blogfiles/itasupport/WindowsLiveWriter/MemoriaPagedeNonPagedPoolComerisolvereun_EE09/image008_thumb.jpg" width=521 height=392 mce_src="http://blogs.technet.com/blogfiles/itasupport/WindowsLiveWriter/MemoriaPagedeNonPagedPoolComerisolvereun_EE09/image008_thumb.jpg"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P align=center&gt;FIG 1 - Output del tool Poolmon.exe&lt;/P&gt;
&lt;P&gt;I campi fondamentali per la nostra analisi sono evidenziati in rosso:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Tag&lt;/STRONG&gt;&lt;EM&gt;: Rappresenta il TAG che identifica l'allocazione.&lt;/EM&gt; &lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Type&lt;/STRONG&gt;&lt;EM&gt;: Specifica se la memoria è stata allocata in Paged (Paged) o Nonpaged (Nonp) pool.&lt;/EM&gt; &lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Bytes&lt;/STRONG&gt;&lt;EM&gt;: Quantità di memoria allocata, in bytes, per il corrispondente TAG&lt;/EM&gt; &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Possiamo, dunque, utilizzare i seguenti passi per raccogliere l'output del poolmon in una finestra temporale di nostro interesse:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Copiare il file "&lt;B&gt;PoolMon.exe&lt;/B&gt;" in "C:\PoolMon", inserendo nella stessa cartella il tool &lt;B&gt;sleep.exe&lt;/B&gt; &lt;/LI&gt;
&lt;LI&gt;Aprire una &lt;B&gt;console dei comandi &lt;/B&gt;da "Start" --&amp;gt; "All programs" --&amp;gt; "Accessories" --&amp;gt; "Command Prompt" &lt;/LI&gt;
&lt;LI&gt;Spostare il prompt in &lt;B&gt;C:\PoolMon&lt;/B&gt; &lt;/LI&gt;
&lt;LI&gt;Per avere una lettura dei dati ogni 15 minuti (per 2 giorni circa), digitare il seguente comando: &lt;BR&gt;&lt;FONT face="Courier New"&gt;&lt;STRONG&gt;for /l %i in (1,1,200) do ( poolmon -n log-%i.txt &amp;amp;&amp;amp; sleep 900000 )&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI&gt;Nella cartella "&lt;B&gt;C:\PoolMon&lt;/B&gt;" verranno creati i vari file di log. &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;Il tool &lt;B&gt;sleep.exe&lt;/B&gt; utilizzato è fornito in allegato al presente post.&lt;/P&gt;
&lt;H3&gt;Determinare la frequenza di campionamento&lt;/H3&gt;
&lt;P&gt;Sleep.exe richiede un parametro che indica il &lt;STRONG&gt;periodo d'attesa in millisecondi&lt;/STRONG&gt; tra due esecuzioni del ciclo for. &lt;BR&gt;Nell’esempio di script riportato sopra, abbiamo il parametro 900’000 che è ottenuto moltiplicando: 15 minuti * 60 secondi * 1000 millisecondi per ottenere una pausa tra una lettura e l’altra di &lt;STRONG&gt;15 minuti&lt;/STRONG&gt;.&lt;/P&gt;
&lt;P&gt;Considerando i 200 cicli impostati ogni 15 minuti, abbiamo un &lt;STRONG&gt;campionamento di circa 2 giorni&lt;/STRONG&gt; calcolato da: 15 minuti/campione * 200 campioni = 3000 minuti totali / 60 = 50 ore totali / 24 = 2,08 giorni.&lt;/P&gt;
&lt;P&gt;Possiamo modificare il numero di cicli e la frequenza di campionamento in base alla rapidità del leak che abbiamo identificato.&lt;/P&gt;
&lt;P&gt;Al termine del periodo di monitoring, avremo dunque &lt;STRONG&gt;200 file di testo&lt;/STRONG&gt;, che iniziano con log1.txt fino a&amp;nbsp; log200.txt nel nostro esempio.&lt;/P&gt;
&lt;P&gt;Copiando questi dati in un foglio Excel ed ordinandoli in base al tipo (Nonp o Paged) e in ordine decrescente rispetto ai byte allocati, saremo in grado di determinare la variazione di allocazione dei TAG in funzione del tempo, identificando quali, in particolare, stanno occupando di più.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.technet.com/blogfiles/itasupport/WindowsLiveWriter/MemoriaPagedeNonPagedPoolComerisolvereun_EE09/clip_image006_2.jpg" mce_href="http://blogs.technet.com/blogfiles/itasupport/WindowsLiveWriter/MemoriaPagedeNonPagedPoolComerisolvereun_EE09/clip_image006_2.jpg"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: block; FLOAT: none; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; MARGIN-LEFT: auto; BORDER-LEFT-WIDTH: 0px; MARGIN-RIGHT: auto" title=clip_image006 border=0 alt=clip_image006 src="http://blogs.technet.com/blogfiles/itasupport/WindowsLiveWriter/MemoriaPagedeNonPagedPoolComerisolvereun_EE09/clip_image006_thumb.jpg" width=534 height=246 mce_src="http://blogs.technet.com/blogfiles/itasupport/WindowsLiveWriter/MemoriaPagedeNonPagedPoolComerisolvereun_EE09/clip_image006_thumb.jpg"&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P align=center&gt;FIG 2 - Schermata di Excel per l'ordinamento dei TAG.&lt;/P&gt;
&lt;H3&gt;Analizzare i log&lt;/H3&gt;
&lt;P&gt;Avremo risultati di questo tipo:&lt;/P&gt;
&lt;H4&gt;NonPaged Pool&lt;/H4&gt;
&lt;TABLE border=0 cellSpacing=0 cellPadding=2 width=401&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD width=133 align=middle&gt;
&lt;P&gt;NonPaged - Log 1&lt;/P&gt;&lt;/TD&gt;
&lt;TD width=133 align=middle&gt;
&lt;P&gt;NonPaged - Log 10&lt;/P&gt;&lt;/TD&gt;
&lt;TD width=133 align=middle&gt;
&lt;P&gt;NonPaged - Log 20&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD vAlign=top width=133&gt;&lt;A href="http://blogs.technet.com/blogfiles/itasupport/WindowsLiveWriter/MemoriaPagedeNonPagedPoolComerisolvereun_EE09/clip_image002_2.jpg" mce_href="http://blogs.technet.com/blogfiles/itasupport/WindowsLiveWriter/MemoriaPagedeNonPagedPoolComerisolvereun_EE09/clip_image002_2.jpg"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image002 border=0 alt=clip_image002 src="http://blogs.technet.com/blogfiles/itasupport/WindowsLiveWriter/MemoriaPagedeNonPagedPoolComerisolvereun_EE09/clip_image002_thumb.jpg" width=249 height=250 mce_src="http://blogs.technet.com/blogfiles/itasupport/WindowsLiveWriter/MemoriaPagedeNonPagedPoolComerisolvereun_EE09/clip_image002_thumb.jpg"&gt;&lt;/A&gt;&lt;/TD&gt;
&lt;TD vAlign=top width=133&gt;&lt;A href="http://blogs.technet.com/blogfiles/itasupport/WindowsLiveWriter/MemoriaPagedeNonPagedPoolComerisolvereun_EE09/clip_image002%5B5%5D.jpg" mce_href="http://blogs.technet.com/blogfiles/itasupport/WindowsLiveWriter/MemoriaPagedeNonPagedPoolComerisolvereun_EE09/clip_image002%5B5%5D.jpg"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image002[5] border=0 alt=clip_image002[5] src="http://blogs.technet.com/blogfiles/itasupport/WindowsLiveWriter/MemoriaPagedeNonPagedPoolComerisolvereun_EE09/clip_image002%5B5%5D_thumb.jpg" width=255 height=249 mce_src="http://blogs.technet.com/blogfiles/itasupport/WindowsLiveWriter/MemoriaPagedeNonPagedPoolComerisolvereun_EE09/clip_image002%5B5%5D_thumb.jpg"&gt;&lt;/A&gt;&lt;/TD&gt;
&lt;TD vAlign=top width=133&gt;&lt;A href="http://blogs.technet.com/blogfiles/itasupport/WindowsLiveWriter/MemoriaPagedeNonPagedPoolComerisolvereun_EE09/clip_image002%5B7%5D.jpg" mce_href="http://blogs.technet.com/blogfiles/itasupport/WindowsLiveWriter/MemoriaPagedeNonPagedPoolComerisolvereun_EE09/clip_image002%5B7%5D.jpg"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image002[7] border=0 alt=clip_image002[7] src="http://blogs.technet.com/blogfiles/itasupport/WindowsLiveWriter/MemoriaPagedeNonPagedPoolComerisolvereun_EE09/clip_image002%5B7%5D_thumb.jpg" width=248 height=251 mce_src="http://blogs.technet.com/blogfiles/itasupport/WindowsLiveWriter/MemoriaPagedeNonPagedPoolComerisolvereun_EE09/clip_image002%5B7%5D_thumb.jpg"&gt;&lt;/A&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;H4&gt;Paged Pool&lt;/H4&gt;
&lt;TABLE border=0 cellSpacing=0 cellPadding=2 width=401&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD width=133 align=middle&gt;
&lt;P&gt;Paged - Log 1&lt;/P&gt;&lt;/TD&gt;
&lt;TD width=133 align=middle&gt;
&lt;P&gt;Paged - Log 10&lt;/P&gt;&lt;/TD&gt;
&lt;TD width=133 align=middle&gt;
&lt;P&gt;Paged - Log 20&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD vAlign=top width=133&gt;&lt;A href="http://blogs.technet.com/blogfiles/itasupport/WindowsLiveWriter/MemoriaPagedeNonPagedPoolComerisolvereun_EE09/clip_image002%5B10%5D.jpg" mce_href="http://blogs.technet.com/blogfiles/itasupport/WindowsLiveWriter/MemoriaPagedeNonPagedPoolComerisolvereun_EE09/clip_image002%5B10%5D.jpg"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image002[10] border=0 alt=clip_image002[10] src="http://blogs.technet.com/blogfiles/itasupport/WindowsLiveWriter/MemoriaPagedeNonPagedPoolComerisolvereun_EE09/clip_image002%5B10%5D_thumb.jpg" width=245 height=188 mce_src="http://blogs.technet.com/blogfiles/itasupport/WindowsLiveWriter/MemoriaPagedeNonPagedPoolComerisolvereun_EE09/clip_image002%5B10%5D_thumb.jpg"&gt;&lt;/A&gt;&lt;/TD&gt;
&lt;TD vAlign=top width=133&gt;&lt;A href="http://blogs.technet.com/blogfiles/itasupport/WindowsLiveWriter/MemoriaPagedeNonPagedPoolComerisolvereun_EE09/clip_image002%5B12%5D.jpg" mce_href="http://blogs.technet.com/blogfiles/itasupport/WindowsLiveWriter/MemoriaPagedeNonPagedPoolComerisolvereun_EE09/clip_image002%5B12%5D.jpg"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image002[12] border=0 alt=clip_image002[12] src="http://blogs.technet.com/blogfiles/itasupport/WindowsLiveWriter/MemoriaPagedeNonPagedPoolComerisolvereun_EE09/clip_image002%5B12%5D_thumb.jpg" width=251 height=190 mce_src="http://blogs.technet.com/blogfiles/itasupport/WindowsLiveWriter/MemoriaPagedeNonPagedPoolComerisolvereun_EE09/clip_image002%5B12%5D_thumb.jpg"&gt;&lt;/A&gt;&lt;/TD&gt;
&lt;TD vAlign=top width=133&gt;&lt;A href="http://blogs.technet.com/blogfiles/itasupport/WindowsLiveWriter/MemoriaPagedeNonPagedPoolComerisolvereun_EE09/clip_image002%5B14%5D.jpg" mce_href="http://blogs.technet.com/blogfiles/itasupport/WindowsLiveWriter/MemoriaPagedeNonPagedPoolComerisolvereun_EE09/clip_image002%5B14%5D.jpg"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image002[14] border=0 alt=clip_image002[14] src="http://blogs.technet.com/blogfiles/itasupport/WindowsLiveWriter/MemoriaPagedeNonPagedPoolComerisolvereun_EE09/clip_image002%5B14%5D_thumb.jpg" width=241 height=192 mce_src="http://blogs.technet.com/blogfiles/itasupport/WindowsLiveWriter/MemoriaPagedeNonPagedPoolComerisolvereun_EE09/clip_image002%5B14%5D_thumb.jpg"&gt;&lt;/A&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;TABLE cellSpacing=0 cellPadding=0&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD width=12&gt;&lt;/TD&gt;
&lt;TD width=274&gt;&lt;/TD&gt;
&lt;TD width=17&gt;&lt;/TD&gt;
&lt;TD width=274&gt;&lt;/TD&gt;
&lt;TD width=15&gt;&lt;/TD&gt;
&lt;TD width=274&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;/TD&gt;
&lt;TD width=274&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;/TD&gt;
&lt;TD width=274&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;/TD&gt;
&lt;TD width=274&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;P&gt;Come possiamo notare è evidente un notevole incremento del TAG &lt;B&gt;Pipo&lt;/B&gt; per la Nonpaged pool. &lt;BR&gt;Analizzando anche i restanti log abbiamo infatti il seguente andamento:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.technet.com/blogfiles/itasupport/WindowsLiveWriter/MemoriaPagedeNonPagedPoolComerisolvereun_EE09/clip_image020_2.jpg" mce_href="http://blogs.technet.com/blogfiles/itasupport/WindowsLiveWriter/MemoriaPagedeNonPagedPoolComerisolvereun_EE09/clip_image020_2.jpg"&gt;&lt;IMG style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; DISPLAY: block; FLOAT: none; MARGIN-LEFT: auto; BORDER-TOP: 0px; MARGIN-RIGHT: auto; BORDER-RIGHT: 0px" title=clip_image020 border=0 alt=clip_image020 src="http://blogs.technet.com/blogfiles/itasupport/WindowsLiveWriter/MemoriaPagedeNonPagedPoolComerisolvereun_EE09/clip_image020_thumb.jpg" width=521 height=267 mce_src="http://blogs.technet.com/blogfiles/itasupport/WindowsLiveWriter/MemoriaPagedeNonPagedPoolComerisolvereun_EE09/clip_image020_thumb.jpg"&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P align=center&gt;FIG 3 - Andamento della Nonpaged pool allocata dal TAG Pipo.&lt;/P&gt;
&lt;P&gt;Come è possibile notare è presente un leak sul TAG Pipo. Ora che abbiamo identificato il TAG che sta alla base del memory leak, come possiamo identificarne il driver corrispondente?&lt;/P&gt;
&lt;H3&gt;Identificare il driver&lt;/H3&gt;
&lt;P&gt;L’elenco di tutti i TAG utilizzati per le allocazioni nella memoria Pool sono disponibili nel file &lt;I&gt;&lt;STRONG&gt;Pooltag.txt&lt;/STRONG&gt; &lt;BR&gt;&lt;/I&gt;Questo file contiene l’identificativo di tutti i componenti Kernel-mode e driver rilasciati con i Sistemi Operativi Windows.&lt;/P&gt;
&lt;P&gt;E’ disponibile per il download e l’installazione all’interno dei &lt;A href="http://www.microsoft.com/whdc/devtools/debugging/default.mspx" target=_blank mce_href="http://www.microsoft.com/whdc/devtools/debugging/default.mspx"&gt;&lt;STRONG&gt;Debugging Tools for Windows&lt;/STRONG&gt;&lt;/A&gt;:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://www.microsoft.com/whdc/devtools/debugging/installx86.mspx" target=_blank mce_href="http://www.microsoft.com/whdc/devtools/debugging/installx86.mspx"&gt;Debugging Tools for Windows 32-bit Version&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://www.microsoft.com/whdc/devtools/debugging/install64bit.mspx" target=_blank&gt;Debugging Tools for Windows 64-bit Version&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Un esempio del contenuto del file Pooltag.txt è riportato di seguito:&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P align=left&gt;&lt;FONT face="Courier New"&gt;8042 - i8042prt.sys - PS/2 kb and mouse &lt;BR&gt;AdSv - vmsrvc.sys&amp;nbsp;&amp;nbsp; - Virtual Machines Additions Service &lt;BR&gt;ARPC - atmarpc.sys&amp;nbsp; - ATM ARP Client &lt;BR&gt;ATMU - atmuni.sys&amp;nbsp;&amp;nbsp; - ATM UNI Call Manager &lt;BR&gt;ACPI - acpi.sys&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; - ACPI &lt;BR&gt;Afd? - afd.sys&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; - AFD objects &lt;BR&gt;AfdA - afd.sys&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; - Afd EA buffer&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Se il TAG che causa il leak di memoria non è contenuti nell’elenco, vi consiglio di effettuare una ricerca nella nostra &lt;STRONG&gt;Knowledge Base&lt;/STRONG&gt;, in modo da verificare la presenza di eventuali problemi conosciuti e installare la relativa hotfix.&lt;/P&gt;
&lt;P&gt;Se invece, come nel caso del nostro esempio, il TAG non è Microsoft non sarà presente nell'elenco. &lt;BR&gt;In questo caso possiamo utilizzare il comando &lt;B&gt;findstr&lt;/B&gt;, valido per ciascuna versione di Windows, che potrà essere eseguito come indicato di seguito:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Aprire una &lt;B&gt;console dei comandi &lt;/B&gt;da "Start" --&amp;gt; "All programs" --&amp;gt; "Accessories" --&amp;gt; "Command Prompt"&lt;/LI&gt;
&lt;LI&gt;Spostarsi nella cartella&lt;B&gt; %systemroot%\system32\drivers&lt;/B&gt;&lt;/LI&gt;
&lt;LI&gt;Digitare il comando &lt;BR&gt;&lt;FONT face="Courier New"&gt;&lt;STRONG&gt;findstr /m /l &amp;lt;tag&amp;gt; *.sys&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI&gt;Verificare l'output restituito dal comando&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;In questo screenshot è evidenziata la ricerca per il TAG Pipo:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.technet.com/blogfiles/itasupport/WindowsLiveWriter/MemoriaPagedeNonPagedPoolComerisolvereun_EE09/clip_image022_2.jpg" mce_href="http://blogs.technet.com/blogfiles/itasupport/WindowsLiveWriter/MemoriaPagedeNonPagedPoolComerisolvereun_EE09/clip_image022_2.jpg"&gt;&lt;IMG style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; DISPLAY: block; FLOAT: none; MARGIN-LEFT: auto; BORDER-TOP: 0px; MARGIN-RIGHT: auto; BORDER-RIGHT: 0px" title=clip_image022 border=0 alt=clip_image022 src="http://blogs.technet.com/blogfiles/itasupport/WindowsLiveWriter/MemoriaPagedeNonPagedPoolComerisolvereun_EE09/clip_image022_thumb.jpg" width=443 height=79 mce_src="http://blogs.technet.com/blogfiles/itasupport/WindowsLiveWriter/MemoriaPagedeNonPagedPoolComerisolvereun_EE09/clip_image022_thumb.jpg"&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;Come possiamo notare è restituito il driver corrispondente al TAG specificato “Pipo”.&lt;/P&gt;
&lt;P&gt;In questo caso occorrerà verificare un'eventuale versione aggiornata del driver Pippo.sys, o eventualmente contattare il fornitore del software segnalando la problematica.&lt;/P&gt;
&lt;H3&gt;Conclusione&lt;/H3&gt;
&lt;P&gt;Alla luce di quanto visto fino ad ora, se stiamo evidenziando un leak di memoria sul nostro sistema potremo identificarne la potenziale causa attraverso i seguenti passi:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Monitorare i byte allocati da ciascun TAG durante una finestra temporale adeguata al nostro leak, attraverso il tool &lt;STRONG&gt;poolmon.exe&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;Evidenziare eventuali &lt;STRONG&gt;allocazioni&lt;/STRONG&gt; che variano proporzionalmente al tempo in &lt;STRONG&gt;costante crescita&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;Stabilire su che &lt;STRONG&gt;tipo di pool&lt;/STRONG&gt; è presente il leak (Paged o Nonpaged)&lt;/LI&gt;
&lt;LI&gt;Stabilire il &lt;STRONG&gt;driver associato &lt;/STRONG&gt;al TAG che sta causando il leak&lt;/LI&gt;
&lt;LI&gt;Ricercare eventuali &lt;STRONG&gt;problemi noti&lt;/STRONG&gt;, o analizzare la problematica con il &lt;STRONG&gt;fornitore &lt;/STRONG&gt;del driver&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&lt;A href="http://blogs.technet.com/itasupport/pages/mattia-tocco.aspx" mce_href="http://blogs.technet.com/itasupport/pages/mattia-tocco.aspx"&gt;Mattia Tocco&lt;/A&gt; &lt;BR&gt;Senior Support Engineer &lt;BR&gt;Microsoft Enterprise Platform Support&lt;/P&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3239803" width="1" height="1"&gt;</description><enclosure url="http://blogs.technet.com/itasupport/attachment/3239803.ashx" length="16896" type="application/octet-stream" /><category domain="http://blogs.technet.com/itasupport/archive/tags/Windows+Team/default.aspx">Windows Team</category><category domain="http://blogs.technet.com/itasupport/archive/tags/Mattia+Tocco/default.aspx">Mattia Tocco</category><category domain="http://blogs.technet.com/itasupport/archive/tags/Performance/default.aspx">Performance</category><category domain="http://blogs.technet.com/itasupport/archive/tags/NT+Kernel+Architecture/default.aspx">NT Kernel Architecture</category></item><item><title>Memoria Paged e NonPaged Pool – Come identificare un memory leak</title><link>http://blogs.technet.com/itasupport/archive/2009/05/11/memoria-paged-e-nonpaged-pool-come-identificare-un-memory-leak.aspx</link><pubDate>Mon, 11 May 2009 02:00:00 GMT</pubDate><guid isPermaLink="false">d5e57398-b9ef-4490-9955-07cbb4e4a80d:3236896</guid><dc:creator>itentblg</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.technet.com/itasupport/comments/3236896.aspx</comments><wfw:commentRss>http://blogs.technet.com/itasupport/commentrss.aspx?PostID=3236896</wfw:commentRss><description>&lt;p&gt;In questo post vedremo come identificare le problematiche legate ad un esaurimento di due specifiche &lt;a href="http://blogs.technet.com/itasupport/archive/2008/12/15/kernel-memory-overview.aspx" target="_blank"&gt;risorse Kernel&lt;/a&gt;: Paged Pool e NonPaged Pool.     &lt;br /&gt;Vi consiglio di leggere il post di &lt;a href="http://blogs.technet.com/itasupport/pages/fabio-lavatelli.aspx" target="_blank"&gt;Fabio Lavatelli&lt;/a&gt; per una visione esaustiva della memoria: &lt;b&gt;&lt;a href="http://blogs.technet.com/itasupport/archive/2008/12/15/kernel-memory-overview.aspx" target="_blank"&gt;Kernel Memory Overview&lt;/a&gt;.&lt;/b&gt;&lt;/p&gt;  &lt;h3&gt;Memoria Paged e NonPaged Pool&lt;/h3&gt;  &lt;p&gt;All’avvio del computer, il &lt;strong&gt;Memory Manager&lt;/strong&gt; crea dinamicamente due memorie pool di dimensione fissa per tutto il periodo in cui il Sistema Operativo rimane attivo: queste due pool sono conosciute come &lt;b&gt;Paged Pool&lt;/b&gt; e &lt;b&gt;NonPaged Pool&lt;/b&gt;.&lt;/p&gt;  &lt;p&gt;Le dimensioni di queste pool, determinate all'avvio, dipendono da una &lt;strong&gt;serie di fattori&lt;/strong&gt;: alcuni di questi possono essere modificati attraverso specifiche chiavi di registry, mentre altri dipendono dall’hardware specifico del computer, come la quantità di &lt;strong&gt;memoria fisica&lt;/strong&gt;.&lt;/p&gt;  &lt;div&gt;Entrambe le pool possono raggiungere un &lt;strong&gt;valore massimo teorico&lt;/strong&gt; dipendente dall’architettura del sistema operativo:&lt;/div&gt;  &lt;table border="0" cellspacing="0" cellpadding="0" width="577" align="center"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td width="96"&gt;         &lt;p align="center"&gt;&lt;b&gt;Tipo Pool&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td width="284"&gt;         &lt;p align="center"&gt;&lt;b&gt;Sistemi a 32-Bit (x86)&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td width="195"&gt;         &lt;p align="center"&gt;&lt;b&gt;Sistemi a 64-Bit (x64)&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="97"&gt;         &lt;p align="center"&gt;NonPaged&lt;/p&gt;       &lt;/td&gt;        &lt;td width="284"&gt;         &lt;p align="left"&gt;256 MB (Windows 2000, XP e 2003)            &lt;br /&gt;128 MB (Con opzione /3GB abilitata al boot)&lt;/p&gt;       &lt;/td&gt;        &lt;td width="195"&gt;         &lt;p align="center"&gt;128 GB&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="98"&gt;         &lt;p align="center"&gt;Paged&lt;/p&gt;       &lt;/td&gt;        &lt;td width="284"&gt;         &lt;p align="left"&gt;491,875 MB (Windows 2000 e Windows XP) 650,000 MB (Windows Server 2003)&lt;/p&gt;       &lt;/td&gt;        &lt;td width="195"&gt;         &lt;p align="center"&gt;128GB&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;Nel caso sia abilitata l’&lt;strong&gt;opzione /3GB&lt;/strong&gt; nel file boot.ini la dimensione massima teorica della &lt;strong&gt;NonPaged Pool è dimezzata&lt;/strong&gt;. Questo è dovuto alla gestione nel Sistema Operativo della &lt;a href="http://blogs.technet.com/itasupport/archive/2008/12/15/kernel-memory-overview.aspx" target="_blank"&gt;memoria virtuale&lt;/a&gt;: sono dedicati 3 Gigabyte alla parte applicativa e solo 1 Gigabyte alla parte kernel.&lt;/p&gt;  &lt;p&gt;I Sistemi Operativi a 64 bit (x64) presentano limiti di memoria virtuale superiori di diversi ordini di grandezza rispetto a sistemi a 32 bit (x86), perciò un'eventuale saturazione della memoria disponibile avverrebbe in tempi più elevati.&lt;/p&gt;  &lt;p&gt;La sostanziale differenza tra le due tipologie di pool, come evidenzia il nome, è che la Paged Pool può essere &lt;strong&gt;paginata su disco&lt;/strong&gt;, mentre la NonPaged Pool è sempre &lt;strong&gt;residente in memoria&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;I &lt;strong&gt;driver&lt;/strong&gt; utilizzano la NonPaged Pool per tutte quelle operazioni eseguite ad un &lt;strong&gt;Interrupt Request Level&lt;/strong&gt; (IRQL) troppo elevato per ammettere paginazione.     &lt;br /&gt;L'IRQL definisce la priorità a cui il processore sta operando, maggiori informazioni sono disponibili nel seguente articolo: &lt;a href="http://www.microsoft.com/whdc/driver/kernel/IRQL.mspx" target="_blank"&gt;Scheduling, Thread Context, and IRQL&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;Eventi SRV 2019 e 2020&lt;/h3&gt;  &lt;p&gt;Nel caso in cui un driver abbia un funzionamento anomalo, potrebbe allocare memoria Pool senza mai rilasciarla arrivando alla saturazione di tutto lo spazio a disposizione: questo fenomeno è chiamato &lt;strong&gt;memory leak&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;In questo tipo di scenario, generalmente troviamo nel Log degli Eventi di Sistema i seguenti 2 eventi specifici.    &lt;br /&gt;L'&lt;strong&gt;evento 2019&lt;/strong&gt; si riferisce all'esaurimento della &lt;strong&gt;NonPaged pool&lt;/strong&gt;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;Type: Error        &lt;br /&gt;Date: &amp;lt;date&amp;gt;         &lt;br /&gt;Time: &amp;lt;time&amp;gt;         &lt;br /&gt;Event ID: &lt;strong&gt;&lt;font color="#ff0000"&gt;2019&lt;/font&gt;&lt;/strong&gt;         &lt;br /&gt;Source: Srv         &lt;br /&gt;User: N/A         &lt;br /&gt;Computer: &amp;lt;ComputerName&amp;gt;         &lt;br /&gt;Details: The server was unable to allocate from the &lt;font color="#ff0000"&gt;&lt;strong&gt;system&lt;/strong&gt; &lt;strong&gt;NonPaged pool&lt;/strong&gt;&lt;/font&gt; because the pool was empty. &lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Mentre l'&lt;strong&gt;evento 2020&lt;/strong&gt; riguarda l'esaurimento della &lt;strong&gt;Paged Pool&lt;/strong&gt;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;Type: Error        &lt;br /&gt;Date: &amp;lt;date&amp;gt;         &lt;br /&gt;Time: &amp;lt;time&amp;gt;         &lt;br /&gt;Event ID: &lt;strong&gt;&lt;font color="#ff0000"&gt;2020&lt;/font&gt;&lt;/strong&gt;         &lt;br /&gt;Source: Srv         &lt;br /&gt;User: N/A         &lt;br /&gt;Computer: &amp;lt;ComputerName&amp;gt;         &lt;br /&gt;Details: The server was unable to allocate from the &lt;strong&gt;&lt;font color="#ff0000"&gt;system Paged pool&lt;/font&gt;&lt;/strong&gt; because the pool was empty&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;In alcuni scenari specifici di memory leak, gli eventi 2019 e 2020 non sono presenti nel Registro Eventi, ma sono loggati molti errori &lt;strong&gt;333 - &lt;/strong&gt;&lt;strong&gt;Application Popup&lt;/strong&gt;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;Type: Error        &lt;br /&gt;Date: &amp;lt;date&amp;gt;         &lt;br /&gt;Time: &amp;lt;time&amp;gt;         &lt;br /&gt;Event ID: &lt;strong&gt;&lt;font color="#ff0000"&gt;333&lt;/font&gt;&lt;/strong&gt;         &lt;br /&gt;Source: Application Popup         &lt;br /&gt;User: N/A         &lt;br /&gt;Computer: &amp;lt;ComputerName&amp;gt;         &lt;br /&gt;Details: An &lt;strong&gt;&lt;font color="#ff0000"&gt;I/O operation initiated by the Registry failed unrecoverably&lt;/font&gt;&lt;/strong&gt;. The Registry could not read in, or write out, or flush, one of the files that contain the system's image of the Registry&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Maggiori informazioni riguardo questo scenario sono spiegati nel post &lt;a href="http://blogs.technet.com/itasupport/archive/2008/11/17/analizzare-l-evento-application-popup-333.aspx" target="_blank"&gt;Analizzare l’evento “Application Popup 333”&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;Analizzare un Memory Leak&lt;/h3&gt;  &lt;p&gt;Il &lt;strong&gt;comportamento&lt;/strong&gt; del Sistema Operativo in presenza di un memory leak è imprevedibile: si possono registrare &lt;strong&gt;hang&lt;/strong&gt;, &lt;strong&gt;crash&lt;/strong&gt; di applicazioni o &lt;strong&gt;BlueScreen&lt;/strong&gt; (bugcheck 0x0000041 MUST_SUCCEED_POOL_EMPTY).&lt;/p&gt;  &lt;div&gt;Il &lt;strong&gt;performance monitor&lt;/strong&gt; permette di verificare lo stato della Memoria Pool con i seguenti &lt;strong&gt;counter&lt;/strong&gt;:&lt;/div&gt;  &lt;div align="center"&gt;   &lt;table border="0" cellspacing="0" cellpadding="0" width="630" align="center"&gt;&lt;tbody&gt;       &lt;tr&gt;         &lt;td valign="bottom" width="209"&gt;           &lt;p align="center"&gt;&lt;b&gt;Counter&lt;/b&gt;&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="bottom" width="419"&gt;           &lt;p align="center"&gt;&lt;b&gt;Description&lt;/b&gt;&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="bottom" width="209"&gt;           &lt;p align="left"&gt;Memory\Paged Pool Bytes&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="bottom" width="419"&gt;           &lt;p align="left"&gt;Indica il numero di byte allocati nella Paged Pool di sistema&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="209"&gt;           &lt;p align="left"&gt;Memory\Non Paged Pool Bytes&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top" width="419"&gt;           &lt;p align="left"&gt;Indica il numero di byte allocati nella NonPaged Pool di sistema&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;     &lt;/tbody&gt;&lt;/table&gt; &lt;/div&gt;  &lt;p&gt;Il grafico seguente illustra un andamento tipo di un &lt;strong&gt;memory leak&lt;/strong&gt; relativo alla NonPaged Pool:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.technet.com/blogfiles/itasupport/WindowsLiveWriter/MemoriaPagedPooleNonPagedPoolComeidentif_84DF/clip_image002_2.gif"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="clip_image002" border="0" alt="clip_image002" src="http://blogs.technet.com/blogfiles/itasupport/WindowsLiveWriter/MemoriaPagedPooleNonPagedPoolComeidentif_84DF/clip_image002_thumb.gif" width="563" height="394" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p align="center"&gt;FIG 1 - Andamento tipico di un memory leak relativo alla NonPaged Pool.&lt;/p&gt;  &lt;p&gt;La NonPaged Pool allocata, indicata in MegaByte, è al di sotto del valore massimo teorico di 256 MB, ma presenta un &lt;strong&gt;andamento crescente&lt;/strong&gt; che indica un tipico caso in cui un driver non stia rilasciando la memoria allocata.&lt;/p&gt;  &lt;p&gt;La &lt;strong&gt;crescita&lt;/strong&gt; può essere variabile in funzione del tempo, e per questo la &lt;strong&gt;finestra temporale&lt;/strong&gt; di monitoring dovrà essere modulata proporzionalmente alla rapidità del leak.&lt;/p&gt;  &lt;p&gt;Il grafico seguente illustra un altro andamento tipo di &lt;strong&gt;saturazione di memoria&lt;/strong&gt; relativo alla NonPaged Pool:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.technet.com/blogfiles/itasupport/WindowsLiveWriter/MemoriaPagedPooleNonPagedPoolComeidentif_84DF/clip_image002%5B5%5D.gif"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="clip_image002[5]" border="0" alt="clip_image002[5]" src="http://blogs.technet.com/blogfiles/itasupport/WindowsLiveWriter/MemoriaPagedPooleNonPagedPoolComeidentif_84DF/clip_image002%5B5%5D_thumb.gif" width="564" height="346" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p align="center"&gt;FIG 2 - Andamento variabile relativo alla NonPaged Pool.&lt;/p&gt;  &lt;p&gt;L’andamento non risulta crescente, ma può indicare ugualmente la presenza di problemi dovuti al raggiungimento del limite massimo di memoria Pool disponibile. In questa situazione non abbiamo un vero e proprio memory leak, ma una saturazione della NonPaged Pool che richiede un &lt;strong&gt;tuning manuale &lt;/strong&gt;di specifiche chiavi di &lt;strong&gt;registry&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;I due andamenti riportati valgono per &lt;strong&gt;entrambe le tipologie di memoria Pool&lt;/strong&gt; anche se i limiti più stringenti e che presentano più problemi sono relativi alla memoria NonPaged Pool.&lt;/p&gt;  &lt;p&gt;Nei successivi post vedremo nel dettaglio come approfondire e risolvere:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Problemi di memory leak &lt;/li&gt;    &lt;li&gt;Problemi di saturazione della memoria &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.technet.com/itasupport/pages/mattia-tocco.aspx"&gt;Mattia Tocco&lt;/a&gt;     &lt;br /&gt;Senior Support Engineer     &lt;br /&gt;Microsoft Enterprise Platform Support&lt;/p&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3236896" width="1" height="1"&gt;</description><category domain="http://blogs.technet.com/itasupport/archive/tags/Mattia+Tocco/default.aspx">Mattia Tocco</category><category domain="http://blogs.technet.com/itasupport/archive/tags/Performance/default.aspx">Performance</category><category domain="http://blogs.technet.com/itasupport/archive/tags/NT+Kernel+Architecture/default.aspx">NT Kernel Architecture</category><category domain="http://blogs.technet.com/itasupport/archive/tags/Pool+Memory/default.aspx">Pool Memory</category></item><item><title>Kernel Memory Overview</title><link>http://blogs.technet.com/itasupport/archive/2008/12/15/kernel-memory-overview.aspx</link><pubDate>Mon, 15 Dec 2008 03:00:00 GMT</pubDate><guid isPermaLink="false">d5e57398-b9ef-4490-9955-07cbb4e4a80d:3168963</guid><dc:creator>itentblg</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.technet.com/itasupport/comments/3168963.aspx</comments><wfw:commentRss>http://blogs.technet.com/itasupport/commentrss.aspx?PostID=3168963</wfw:commentRss><description>&lt;H3&gt;Introduzione&lt;/H3&gt;
&lt;P&gt;Alcuni problemi riportati da applicazioni server, come anche da applicativi tradizionali, possono essere ricondotti all'esaurimento di memoria. Una domanda che spesso ci si pone è se si possa risolvere il problema aumentando la disponibilità di memoria RAM (Random Access Memory), ovvero la memoria fisica installata sul server o sulla workstation. In taluni casi la risposta è affermativa ma sfortunatamente in molte altre situazioni un upgrade hardware non risolve il problema.&lt;/P&gt;
&lt;P&gt;Un errore riportato come un esaurimento di memoria o di risorse può essere riferito ad un particolare tipo di memoria, con certi limiti, i quali non sono correlati alla quantità di memoria totale installata sulla macchina ma primariamente legati all'architettura del processore e a come è stato progettato il sistema operativo.&lt;/P&gt;
&lt;P&gt;In questo post vengono analizzate e classificate le principali risorse di memoria gestite dal sistema operativo, sono poi considerati gli scenari generici di esaurimento per i vari casi trattati. In un seguente post si vedranno i principali parametri da verificare ed un cenno alle metodologie di troubleshooting. Poiché la piattaforma a 32 bit è più soggetta a problemi di esaurimento di risorse, per le evidenti limitazioni rispetto a quella a 64 bit, essa sarà l'oggetto primario del post. Le informazioni architetturali trattate sono comunque valide per ogni sistema Windows e salvo casi particolari applicabili anche alla seconda. Ove si quantifichino dei valori numerici sono invece da considerarsi specifici alla piattaforma a 32 bit.&lt;/P&gt;
&lt;P&gt;I contenuti dei primi post su questa tematica saranno primariamente teorici ed architetturali, introduttivi a quelli che seguiranno da parte mia e dei miei colleghi, indirizzati alla risoluzione di problemi più specifici.&lt;/P&gt;
&lt;H3&gt;Classificazione delle risorse di memoria nel sistema operativo Microsoft Windows&lt;/H3&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;B&gt;Memoria fisica&lt;/B&gt;: con questo termine si intende la memoria RAM installata e presente sul server, si tratta quindi di hardware effettivamente nella macchina. Nelle modalità di esecuzione dei processori nei moderni sistemi operativi (paging abilitato) la memoria fisica non è direttamente accessibile: è sempre necessario un meccanismo di mapping che permetta di indirizzare la memoria virtuale o logica (definita sotto) su quella fisica. I recenti processori Intel a 32 bit supportano un massimo di 64GB di memoria, limitata a questi valori dall'architettura. Quelli a 64 bit ne supportano quantità maggiori e crescenti in futuro.&lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;Memoria virtuale o spazio di indirizzi logico:&lt;/B&gt; tramite il mapping citato sopra vengono presentati 4GB di memoria virtuale al codice che gira sul processore. Tale memoria virtuale può mapparsi sulla memoria fisica, su pagine di memoria riversate sul disco (paging file) o su nessuna destinazione per intervalli di indirizzi virtuali non in uso. &lt;BR&gt;Relativamente a questo argomento i termini &lt;I&gt;logico&lt;/I&gt; e &lt;I&gt;virtuale&lt;/I&gt; sono intercambiabili, più precisamente il primo è parte della terminologia definita da Intel per i propri processori, il secondo è più legato all'ambito dei sistemi operativi, come per esempio Windows, che è stato progettato per essere portabile su differenti architetture, quindi non legato alle terminologie specifiche di particolari tipi di hardware.&lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;Risorse kernel:&lt;/B&gt; il kernel del sistema operativo alloca memoria, per le proprie funzioni e per i driver installati da tre importanti risorse, inaccessibili agli applicativi: due pool (nonpaged e paged) e le System PTE. Il fatto che ci siano tre risorse diverse è per soddisfare certi differenti requisiti, che rendono alcune risorse più preziose di altre, in dettaglio:&lt;/LI&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;B&gt;Non-paged pool:&lt;/B&gt; la caratteristica di quest'area di memoria per le allocazioni del kernel è di essere sempre disponibile e permanentemente mappata su memoria fisica, in altre parole non può essere paginata sul disco di paging, da cui il nome. Date queste sue caratteristiche è più preziosa delle altre due, richiedendo costantemente una quantità di memoria fisica pari alla sua dimensione.&lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;Paged pool:&lt;/B&gt; è un'altra forma di memoria allocabile dai componenti kernel, è meno pregiata, quindi generalmente più abbondante, in quanto all'occorrenza può essere oggetto di paging (swap) per liberare memoria fisica ad altre esigenze.&lt;/LI&gt;&lt;/UL&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;B&gt;System PTE:&lt;/B&gt; sono degli elementi di allocazione con granularità di una pagina di memoria (4096 byte) ed hanno particolari caratteristiche che le rendono più versatili delle precedenti. Possono essere usate solo per specifici scopi da parte di pochi componenti del kernel, data la complessità di gestione, che è il prezzo della loro versatilità. A titolo di esempio gli stack kernel, i memory mapped device, alcuni tipi di video buffer e i buffer di memoria per trasferimenti di tipo DMA (Direct Memory Access) utilizzano questa risorsa.&lt;/LI&gt;&lt;/UL&gt;&lt;/UL&gt;
&lt;P&gt;Per ciascuna delle risorse citate un consumo eccessivo ed incontrollato può sempre portare all'esaurimento, più frequentemente uno o più componenti possono allocare memoria dei vari tipi e non rilasciarla, tipicamente per un bug, anche in questo caso se non interviene un reboot si arriva più o meno velocemente all'esaurimento. Questo tipo di esaurimento è definito come &lt;I&gt;memory leak&lt;/I&gt;.&lt;/P&gt;
&lt;H3&gt;Aspetti specifici per ciascuna categoria e tipologie di esaurimento&lt;/H3&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;B&gt;Memoria fisica&lt;/B&gt;: sebbene la prima ipotesi a cui si vorrebbe attribuire un esaurimento di memoria sia quasi sempre la memoria fisica, nella realtà gli esaurimenti di questa risorsa sono rari. Il sistema operativo gestisce molto bene la memoria fisica. Potendosi poggiare sul paging file per liberare memoria, è difficile che si arrivi realmente al punto di non averne a sufficienza per le funzioni minime di un server. In realtà la penuria di questa risorsa viene percepita molto presto come un peggioramento progressivo della performance del server che, trovandosi a dover continuamente spostare dati tra memoria fisica ed il file di paging, allo scopo appena citato, diventa molto lento. &lt;BR&gt;In ogni caso, quando si arrivi alla conclusione che un server necessita di 4GB o più, si rende necessario abilitare un kernel alternativo del sistema operativo che sfrutta su una funzionalità del processore denominata PAE (Physical Addressing Extension). Tramite questo meccanismo i 32 bit di indirizzi logici vengono mappati su 36 bit permettendo di indirizzare, e quindi installare, fino a 64GB di memoria fisica. L'abilitazione di questo meccanismo avviene tramite lo switch /PAE nel boot.ini. Questo switch non ha nessuna relazione con il /3GB, descritto sotto e che agisce sugli spazi di indirizzamento logici. &lt;BR&gt;E' da notare che anche con soli 4GB il PAE è necessario per vedere tutta la memoria presente, a causa di un intervallo di indirizzi fisici aggiuntivi occupati da certi dispositivi hardware (es. PCI devices).&lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;Memoria virtuale o spazio di indirizzi logico:&lt;/B&gt; Questo spazio, di 4GB per le architetture a 32 bit, è diviso in due parti che vanno rispettivamente al kernel e agli applicativi, La seconda porzione, per gli applicativi, è strutturata in modo che ognuno ne abbia una sua visione privata, che è alla base della garanzia del loro isolamento. La divisione di default, sin dal design iniziale del sistema operativo Windows NT 3.1, è di 2GB per il kernel e 2GB per lo spazio lasciato agli applicativi. &lt;BR&gt;Il sistema deve ripartire lo spazio kernel, di 2GB, tra le tre risorse del kernel descritte sopra. Questa divisione avviene in modo più o meno statico, a seconda della versione del sistema, e non si arriva mai ad esaurire lo spazio di indirizzi in quanto tale, tuttavia, data la ripartizione appena citata, quello che può succedere è che si esauriscano le singole risorse, i tre casi vengono quindi analizzati oltre. &lt;BR&gt;A livello applicativo, specie per applicazioni server (es. Microsoft SQL Server, Microsoft Exchange Server) il massimo di 2GB può essere effettivamente limitante. Per aumentare questa risorsa agli applicativi già da Windows NT4.0 venne introdotto lo switch del boot.ini /3GB. Questa impostazione alternativa permette di offrire 3GB di spazi di indirizzi virtuali agli applicativi, tuttavia questo avviene a scalpito degli spazi kernel che devono limitarsi a 1GB e questa riduzione impatta significativamente le tre risorse kernel, che risultano notevolmente limitate, a grandi linee dimezzate. &lt;BR&gt;Sia nella configurazione tradizionale che /3GB un eventuale esaurimento dello spazio a disposizione degli applicativi potrebbe essere percepito con errori tipo "Out of memory", "Not enough resources" o similari. In questo caso solo l'intervento di supporto di chi ha venduto o sviluppato il software può identificare con precisione se effettivamente si è arrivati a questo esaurimento. &lt;BR&gt;Tecniche che gli sviluppatori hanno a disposizione per poter gestire dati di grandi dimensioni su piattaforme a 32 bit sono AWE (Address Windowing Extension) e l'attivazione di un particolare bit nell'immagine del proprio eseguibile, IMAGE_FILE_LARGE_ADDRESS_AWARE, per essere effettivamente abilitati all'accesso di tutti i 3GB nella configurazione /3GB. I dettagli su queste due tecniche esulano dallo scopo di questo post. Su piattaforma a 64 bit gli applicativi a 64 bit hanno a disposizione un vastissimo spazio di indirizzo che non viene correntemente considerato limitante in alcun modo. Un applicativo a 32 bit, con il bit IMAGE_FILE_LARGE_ADDRESS_AWARE attivo, accede a 4GB su una piattaforma a 64 bit, traendo quindi un certo vantaggio. &lt;BR&gt;E' importante ribadire che tutto quanto descritto in questo paragrafo avviene in termini di spazi di indirizzi virtuali, quindi in modo pressoché indipendente dal numero di GB di memoria fisica disponibile sul server.&lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;Non-paged e paged pool:&lt;/B&gt; l'esaurimento di una delle pool o entrambe causa seri problemi di stabilità. Tutti i componenti kernel del sistema ed i driver non riescono ad allocare memoria anche per semplici operazioni di base. In teoria al permanere di questa penuria il server diventa incapace di svolgere numerose funzioni, il che impedisce di erogare i servizi per il quale è preposto. Nella pratica in numerosi casi si arriva al blue screen o al blocco irreversibile del server, infatti la continuata incapacità di svolgere i propri compiti colpirà prima o poi una funzione vitale del server che può manifestarsi nei modi citati, altresì certi driver non sono perfettamente testati nel gestire queste situazioni limite e quindi espongono dei bug, che normalmente non si vedrebbero, e che possono portare al blue screen. &lt;BR&gt;Nella maggioranza dei casi l'esaurimento delle pool è dovuto a memory leak nei driver o in certi componenti del sistema operativo. In altri casi le applicazioni, sebbene non abbiano accesso diretto per allocare da questa risorsa, posso ugualmente indurre il loro esaurimento. Ciò avviene se richiedono funzioni che nella loro implementazione, nel kernel, alloca dalle pool. Ad esempio un applicativo che aprisse numerosi file o connessioni di rete senza mai chiuderli causerebbe un memory leak, in questo esempio primariamente nella paged pool. &lt;BR&gt;Un server con una configurazione particolarmente complessa, che include molti componenti kernel diversi, quando sotto carico potrebbe arrivare ad esaurire una delle pool, pur non avendo alcun memory leak. &lt;BR&gt;Un dimensionamento non appropriato delle pool, nei valori del Memory Manager (HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management) nel registry, può portare al loro esaurimento in quanto semplicemente insufficienti.&lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;System PTE:&lt;/B&gt; l'esaurimento delle System PTE porta a fenomeni simili a quelli descritti sopra, in questo caso i componenti che allocano questa risorsa sono più interni al sistema e quindi si hanno effetti, dal punto di vista interno al sistema, differenti ma con sintomi paragonabili a quelli appena descritti. Spesso la penuria di System PTE (meno di 3000-5000 PTE libere) porta ad un errore di inizializzazione degli applicativi con codice 0xC0000142 (STATUS_DLL_INIT_FAILED). &lt;BR&gt;Anche in questo caso la maggioranza degli esaurimenti viene identificata in leak su questo tipo di risorsa per mancati rilasci in driver o componenti kernel, l'esempio più classico è il mancato rilascio di buffer di I/O allocati per trasferimenti DMA. &lt;BR&gt;Bug negli applicativi non sono solitamente correlabili a System PTE leak. &lt;BR&gt;Un dimensionamento non appropriato delle System PTE, nei valori del Memory Manager nel registry (valore "SystemPages"), può portare al loro esaurimento in quanto semplicemente insufficienti.&lt;/LI&gt;&lt;/UL&gt;
&lt;H3&gt;Conclusione&lt;/H3&gt;
&lt;P&gt;Questo post ha voluto trattare una classificazione delle risorse comunemente denominate come "risorse di memoria" e gli scenari che possono dar luogo a dei problemi. Costituisce una base teorica per dei post più pratici e rivolti alla risoluzione di problemi reali che verranno trattati in futuro su questo blog.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.technet.com/itasupport/pages/fabio-lavatelli.aspx" mce_href="http://blogs.technet.com/itasupport/pages/fabio-lavatelli.aspx"&gt;Fabio Lavatelli&lt;/A&gt;&lt;BR&gt;Escalation Engineer &lt;BR&gt;Microsoft Enterprise Platform Support&lt;/P&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3168963" width="1" height="1"&gt;</description><category domain="http://blogs.technet.com/itasupport/archive/tags/Windows+Team/default.aspx">Windows Team</category><category domain="http://blogs.technet.com/itasupport/archive/tags/Fabio+Lavatelli/default.aspx">Fabio Lavatelli</category><category domain="http://blogs.technet.com/itasupport/archive/tags/NT+Kernel+Architecture/default.aspx">NT Kernel Architecture</category><category domain="http://blogs.technet.com/itasupport/archive/tags/Debugging/default.aspx">Debugging</category></item></channel></rss>