<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://msmvps.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>la visión de un ingeniero de campo</title><link>http://msmvps.com/blogs/pmackay/default.aspx</link><description>cuando tu trabajo es ver por qué las aplicaciones no funcionan</description><dc:language>en</dc:language><generator>CommunityServer 2008 SP1 (Build: 30619.63)</generator><item><title>Alto consumo de memoria y cursores de datos</title><link>http://msmvps.com/blogs/pmackay/archive/2008/03/20/post33.aspx</link><pubDate>Thu, 20 Mar 2008 21:22:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1548871</guid><dc:creator>pmackay</dc:creator><slash:comments>0</slash:comments><comments>http://msmvps.com/blogs/pmackay/archive/2008/03/20/post33.aspx#comments</comments><description>&lt;p&gt;&lt;span style="COLOR:#ffffff;BACKGROUND-COLOR:#008000;"&gt;Sorpresas&lt;/span&gt; te llevas en la vida, siempre. A pesar de lo que parezca, hoy no ando sermoneador ni nada por el estilo. Es sólo que no se me ocurre como comenzar este post así que escribo lo primero que se me ocurre &lt;img src="http://msmvps.com/emoticons/emotion-1.gif" alt="Smile" /&gt;. Total, lo interesante viene ahora.&lt;/p&gt;
&lt;p&gt;Viaje de emergencia, aplicación ASP con &lt;a href="http://msmvps.com/blogs/pmackay/archive/2007/02/02/netadmin.aspx"&gt;excepciones por falta de memoria (Out Of Memory)&lt;/a&gt;, servicio interrumpido.&lt;br /&gt;Resumen: problemas... un poco de entretención para unos meses muy aburridos.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Síntomas&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Como mencionaba, tenemos una aplicación ASP que de vez en cuando lanza excepciones por falta de memoria, mas conocidos como error 500 &lt;a href="http://support.microsoft.com/kb/294271" target="_blank"&gt;ASP 147&lt;/a&gt;. Obviamente con el reinicio del proceso, todo vuelve a la normalidad, pero luego de la calma, llega la tormenta.&lt;/p&gt;
&lt;p&gt;Como ya es costumbre, se capturaron algunos &lt;em&gt;dumps&lt;/em&gt; de memoria cuando se estaba produciendo el error y se analizaron. Los resultados fueron sorprendentes, los que pasan a ser mostrados ahora.&lt;/p&gt;
&lt;p&gt;Lo primero muy interesante es que el &lt;em&gt;dump &lt;/em&gt;apenas sobrepasaba los 100 megabytes. Un &lt;em&gt;dump&lt;/em&gt; contiene, sin entrar en grandes detalles, los datos privados del proceso y las librerías cargadas entre otras cosas. Si son un poco más de 100 megabytes, ¿cómo es posible que haya falta de memoria?. El administrador de tareas confirmaba que el proceso estaba utilizando algo más de 100 megabytes en &lt;em&gt;working set&lt;/em&gt; y un poco menos en memoria privada&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;¿Entonces?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.microsoft.com/whdc/devtools/debugging/default.mspx"&gt;Debugging Tool For Windows&lt;/a&gt; entra a ayudarnos. Revisando el estado de cada heap, nos encontramos con lo que muestra el bloque de más abajo. Hay muchas columnas y muchos datos, pero fijemos la atención en las columnas que hacen mención a la memoria reservada y comprometida.&lt;/p&gt;
&lt;p&gt;Recordemos que en un sistema operativo Windows, la memoria puede estar en tres estados: libre, reservada y comprometida. Para que una aplicación la pueda utilizar necesita primero reservarla, y luego comprometerla. Después de usarla, la debe des-comprometer (fea palabra, lo sé) y luego liberar (des-reservar, también es fea).&lt;/p&gt;
&lt;table class="" style="BORDER-RIGHT:1px solid;BORDER-TOP:1px solid;BORDER-LEFT:1px solid;WIDTH:100%;BORDER-BOTTOM:1px solid;"&gt;

&lt;tr&gt;
&lt;td class="" style="BACKGROUND-COLOR:#339933;"&gt;&lt;pre&gt;&lt;span style="COLOR:#ffffff;"&gt;  Heap     Flags   Reserv  Commit  Virt   Free  List   UCR  Virt  Lock  Fast 
                    (k)     (k)    (k)     (k) length      blocks cont. heap 
-----------------------------------------------------------------------------
00080000 00000002   15360  13424  14512   2362   514   137    0     9d   L  
    External fragmentation  17 % (514 free blocks)
00180000 00008000      64     12     12     10     1     1    0      0      
002b0000 00001002   22080   9560  17536   1629   231   124   25     5b   L  
    External fragmentation  17 % (231 free blocks)
    Virtual address fragmentation  45 % (124 uncommited ranges)
00550000 00000002    1024     20     20      2     1     1    0      0   L  
00690000 00001002     256     32     32      2     1     1    0      0   L  
01bb0000 00001002     256     12     12      4     1     1    0      0   L  
01bf0000 00001002   39872  11200  29608    722    62    60    0      7   LFH
01c30000 00001002     256     12     12      4     1     1    0      0   L  
01c70000 00001002     256     12     12      4     1     1    0      0   L  
&amp;lt;recortado&amp;gt;
02630000 00001002     256     12     12      2     1     1    0      0   L  
02670000 00001002     256     12     12      4     1     1    0      0   L  
02730000 00001002      64     32     32      4     1     1    0      0   L  
02a20000 00001002    3328   2084   2396    110    23    16    0      0   LFH
02a60000 00001002   19968   7164   8076     35     6    10   21      0   LFH
02f60000 00001003    1280   1152   1152      2     1     1    0    bad      
03470000 00001003    1280    512    512      1     1     1    0    bad      
034b0000 00001003    1280    524    524      2     1     1    0    bad      
034f0000 00001003     256     96     96      0     0     1    0    bad      
03730000 00001003    1280    356    356      1     1     1    0    bad      
03970000 00001003    1280    264    264      0     0     1    0    bad      
049b0000 00001003     256    204    204      3     1     1    0    bad      
049f0000 00001003  130304    128    300     63    11    12    0    bad      
&lt;strong&gt;04a30000 00001003  441600    112    188    101    11    12    0    bad  &amp;lt;-éste
&lt;/strong&gt;04a70000 00001003  167204    352    424    264    49    67    0    bad      
04ab0000 00001003  465716    128  36532    103    20    27    0    bad      
04af0000 00001003  469708    164   1696     92    13    32    0    bad      
04b30000 00001003   46312    324    328    254    47    65    0    bad      
04b70000 00001003    9700    372    372    348    62    64    0    bad      
039c0000 00001002      64     16     16      2     1     1    0      0   L  
04c30000 00001003     256    148    148     92    36     1    0    bad      
&amp;lt;recortado&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;En el listado anterior, vemos que hay un par de &lt;em&gt;heaps&lt;/em&gt; que han reservado (memoria en estado reservado) más de 400 megabytes, pero que sólo están utilizando (memoria en estado comprometido) un poco más de 100 kilobytes. Entre varios, el &lt;em&gt;heap&lt;/em&gt; 04a30000, indicado más arriba en negrilla y con la palabra &amp;quot;&amp;lt;- éste&amp;quot;, es uno de los más grandes.&lt;/p&gt;
&lt;p&gt;Veamos el detalle de este &lt;em&gt;heap&lt;/em&gt; y sus segmentos, listados a continuación.&lt;/p&gt;
&lt;table class="" style="BORDER-RIGHT:1px solid;BORDER-TOP:1px solid;BORDER-LEFT:1px solid;WIDTH:100%;BORDER-BOTTOM:1px solid;"&gt;

&lt;tr&gt;
&lt;td class="" style="BACKGROUND-COLOR:#339933;"&gt;&lt;pre&gt;&lt;span style="COLOR:#ffffff;"&gt;Index   Address  Name      Debugging options enabled
111:   04a30000 
    Segment at 04a30000 to 04a70000 (00010000 bytes committed)
    Segment at 0f940000 to 0fa40000 (00003000 bytes committed)
    Segment at 0fa40000 to 0fc40000 (00001000 bytes committed)
    Segment at 100d0000 to 104d0000 (00001000 bytes committed)
    Segment at 104d0000 to 10cd0000 (00001000 bytes committed)
    Segment at 10cd0000 to 11cd0000 (00001000 bytes committed)
    Segment at 11cd0000 to 13cd0000 (00001000 bytes committed)
    Segment at 13cd0000 to 17cd0000 (00001000 bytes committed)
    Segment at 17ed0000 to 1fed0000 (00001000 bytes committed)
    Segment at 4dbd0000 to 55bd0000 (00001000 bytes committed)
    Segment at 5bb60000 to 5eb60000 (00001000 bytes committed)&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;Mmm... mmm...mmm...mmm (esto me recuerda &lt;a href="http://social.zune.net/artistdetails.aspx?aid=4d310000-0600-11db-89ca-0019b92a3933" target="_blank"&gt;una canción&lt;/a&gt; de hace unos años), la mayoría de ellos no tiene más de 4 kilobytes usados para bloques de varios megabytes reservados. Si las matemáticas no te ayudan ahora, 1000 en hexadecimal es equivalente a 4096 en decimal.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Análisis de la situación&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Recordemos que el manejo de la memoria lo realiza generalmente el sistema operativo aunque algunas aplicaciones pueden utilizar sus propios manejadores de memoria. Desde código ASP (VBScript) o Visual Basic 6.0, como también desde código manejado NO es posible trabajar a este nivel con la memoria. Lo anterior es un problema en un manejador de memoria.&lt;/p&gt;
&lt;p&gt;Si no es ASP, VB. 6.0, ¿qué puede ser? (considerando que no hay componentes desarrollados por el cliente en C o C++)&lt;/p&gt;
&lt;p&gt;La respuesta la da &lt;a href="http://www.iis.net/downloads/default.aspx?tabid=34&amp;amp;g=6&amp;amp;i=1286"&gt;Debug Diagnostics&lt;/a&gt;. Quien creo el heap es &amp;quot;Microsoft Data Access Runtime&amp;quot;, es decir, MDAC. Revisando la versión instalada, comprobamos que es la última con Windows Server 2003 SP2. El camino se pone difícil.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Investigación y resolución&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Involucrando a las personas adecuadas, aprendimos que este comportamiento es considerado &amp;quot;esperado&amp;quot; cuando se cumplen las siguientes condiciones:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Se utilizan recordset del lado del cliente (client-side cursor)&lt;/li&gt;
&lt;li&gt;Se obtienen muchos datos, muchos datos de una tabla &lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Ok ¿client-side cursor?¿que significa &amp;quot;muchos datos&amp;quot;?&lt;/p&gt;
&lt;p&gt;&amp;quot;Cliente&amp;quot; es quien consulta la base de datos, que para este caso es IIS/ASP. En ese caso, los datos se llevan al cliente para ser luego procesados.&lt;/p&gt;
&lt;p&gt;Después de investigar en el código, se encontró que una consulta estaba retornando más de 2 millones de registros. Eso es mucho &lt;img src="http://msmvps.com/emoticons/emotion-1.gif" alt="Smile" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Reproducción&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Decidido a demostrarlo, procedí a hacer unas pruebas con el siguiente código en mi &amp;quot;servidor.&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;img src="http://msmvps.com/blogs/pmackay/post33/33-01b.Png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Y le agregué a mi tabla algo así como 4 millones de registros.&lt;/p&gt;
&lt;p&gt;Después de varias ejecuciones, tanto en paralelo como en serie, los contadores de memoria reservada, comprometida y utilización de procesador mostraron esto:&lt;/p&gt;
&lt;p&gt;&lt;img height="430" src="http://msmvps.com/blogs/pmackay/post33/33-02b.Png" width="578" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Se puede ver que la memoria comprometida (verde) llegó como mucho hasta 300 megabytes, pero la memoria reservada (roja) aumentó sin mostrar intención de disminuir, llegando casi hasta 900 megabytes.&lt;/p&gt;
&lt;p&gt;¿Cuál es la explicación a que no reutilice la memoria reservada y siga reservando más? Al menos yo no tengo la respuesta.&lt;/p&gt;
&lt;p&gt;¿Que sucede cuando llegue a 2 gigabytes? &lt;a href="http://msmvps.com/blogs/pmackay/archive/2007/02/02/netadmin.aspx"&gt;excepciones por falta de memoria (Out Of Memory)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Conclusiones&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;1.- Nunca desplegar &amp;quot;muchos&amp;quot; registros en una página. Mejor aún, nunca pedir muchos registros a la base de datos.&lt;/p&gt;
&lt;p&gt;2.- Utilicen server-side cursors. Hagan la prueba con el mismo código y comparen los resultados. &lt;img src="http://msmvps.com/emoticons/emotion-5.gif" alt="Wink" /&gt;&lt;/p&gt;
&lt;p&gt;Saludos,&lt;br /&gt;Patrick&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1548871" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/pmackay/archive/tags/Memoria+y+GC/default.aspx">Memoria y GC</category><category domain="http://msmvps.com/blogs/pmackay/archive/tags/Casos/default.aspx">Casos</category></item><item><title>Internet Explorer se cuelga por algunos segundos</title><link>http://msmvps.com/blogs/pmackay/archive/2008/01/10/post32.aspx</link><pubDate>Thu, 10 Jan 2008 09:15:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1452044</guid><dc:creator>pmackay</dc:creator><slash:comments>2</slash:comments><comments>http://msmvps.com/blogs/pmackay/archive/2008/01/10/post32.aspx#comments</comments><description>&lt;p&gt;&lt;span style="COLOR:#ffffff;BACKGROUND-COLOR:#008000;"&gt;A&lt;/span&gt; diferencia de los otros casos descritos, en esta oportunidad quien estaba en problemas era yo mismo, con un síntoma que seguro a alguno de ustedes le ha ocurrido antes. Veamos de que se trata.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Síntomas&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Cada vez que abría una nueva instancia de Internet Explorer, como también al abrir una nueva pestaña de una instancia que ya llevase corriendo, algunas veces se demoraba una buena cantidad de segundos (entre 10 y 15 segundos) en quedar disponible para poder usarla. Si bien el proceso se creaba y se pintaba rápidamente (menos de 1 segundo), quedaba como &amp;quot;esperando&amp;quot; algo.&lt;/p&gt;
&lt;p&gt;Esta es una ventana del navegador en ese estado intermedio de espera.&lt;/p&gt;
&lt;p&gt;&lt;img height="330" src="http://msmvps.com/blogs/pmackay/post32/32-01b.png" width="523" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Una vez que la espera termina, el navegador funciona como se espera. Sin embargo, si se deja pasar un tiempo sin hacer nada en la ventana de éste, al tratar de usarlo nuevamente, ya sea creando un tabulador nuevo o incluso cerrando el proceso, otra vez debo esperar una cantidad de segundos similar a la anterior. &lt;/p&gt;
&lt;p&gt;En resumen, mientras esté usando la ventana (haciendo &lt;em&gt;clics&lt;/em&gt;), todo bien. Dejo de usarla un rato, hay que esperar para que reaccione.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Intención de detección del problema&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Aunque sabía que no sería nada fácil encontrar el problema, hice mi intento usando &lt;a href="http://www.microsoft.com/whdc/devtools/debugging/default.mspx"&gt;Debugging Tool For Windows&lt;/a&gt; y atachándome al proceso&amp;nbsp;una vez creara un nuevo tab mientras estaba &amp;quot;esperando&amp;quot;.&lt;/p&gt;
&lt;p&gt;Un listado de los &lt;em&gt;threads&lt;/em&gt; relevantes (0 y 5) y sus &lt;em&gt;stacks&lt;/em&gt; correspondientes en el momento de espera mostraba lo siguiente.&lt;/p&gt;
&lt;table class="" style="BORDER-RIGHT:1px solid;BORDER-TOP:1px solid;BORDER-LEFT:1px solid;WIDTH:100%;BORDER-BOTTOM:1px solid;"&gt;

&lt;tr&gt;
&lt;td class="" style="BACKGROUND-COLOR:#339933;"&gt;&lt;pre&gt;&lt;span style="COLOR:#ffffff;"&gt;   0  Id: 12f0.123c Suspend: 1 Teb: 7efdd000 Unfrozen
ChildEBP RetAddr  
002ce690 7d4e286c ntdll!NtWaitForMultipleObjects+0x15
002ce738 7d94d299 kernel32!WaitForMultipleObjectsEx+0x11a
002ce794 02596029 user32!RealMsgWaitForMultipleObjectsEx+0x152
002ce7b4 0259632d ieui!CoreSC::Wait+0x49
002ce7dc 025960d8 ieui!CoreSC::WaitMessage+0x54
002ce7e8 4640994d ieui!WaitMessageEx+0x33
002ce818 463fabcc ieframe!CBrowserFrame::FrameMessagePump+0x199
002ce824 463fbc3b ieframe!BrowserThreadProc+0x3f
002ce848 463fbb89 ieframe!BrowserNewThreadProc+0x7b
002cf8b8 463fba39 ieframe!SHOpenFolderWindow+0x188
002cfae8 00401464 ieframe!IEWinMain+0x2d9
002cff2c 004012ff iexplore!wWinMain+0x2c1
002cffc0 7d4e7d2a iexplore!_initterm_e+0x1b1
002cfff0 00000000 kernel32!BaseProcessStart+0x28

   5  Id: 12f0.12e8 Suspend: 1 Teb: 7efa9000 Unfrozen
ChildEBP RetAddr  
02fee038 7d4d8c82 ntdll!ZwWaitForSingleObject+0x15
02fee0a8 7da3936a kernel32!WaitForSingleObjectEx+0xac
02fee0c4 7da3ba11 rpcrt4!UTIL_WaitForSyncIO+0x20
02fee0e8 7da3b9eb rpcrt4!UTIL_GetOverlappedResultEx+0x1d
02fee104 7da3b9a9 rpcrt4!UTIL_GetOverlappedResult+0x17
02fee124 7da3ad05 rpcrt4!NMP_SyncSendRecv+0x73
02fee14c 7da3af2d rpcrt4!OSF_CCONNECTION::TransSendReceive+0x7d
02fee1d4 7da3aea2 rpcrt4!OSF_CCONNECTION::SendFragment+0x2ae
02fee22c 7da3b1b9 rpcrt4!OSF_CCALL::SendNextFragment+0x1e2
02fee274 7da3b834 rpcrt4!OSF_CCALL::FastSendReceive+0x148
02fee290 7da3b7b7 rpcrt4!OSF_CCALL::SendReceiveHelper+0x5b
02fee2c0 7da37d3e rpcrt4!OSF_CCALL::SendReceive+0x41
02fee2cc 7da37cf0 rpcrt4!I_RpcSendReceive+0x24
02fee2e0 7dac01b6 rpcrt4!NdrSendReceive+0x2b
02fee6c8 71c4b685 rpcrt4!NdrClientCall2+0x22e
02fee6e0 71c4b644 netapi32!NetrLogonGetTrustRid+0x1c
02fee720 7da4af08 netapi32!I_NetlogonGetTrustRid+0x1e
02fee768 7da4ae60 rpcrt4!GetMachineAccountSid+0xcb
02fee780 7da3f97e rpcrt4!NormalizeAccountSid+0x4c
02fee88c 7da4aaa4 rpcrt4!LRPC_CASSOCIATION::OpenLpcPort+0x1e9
02feeb88 7da4a40b rpcrt4!LRPC_CASSOCIATION::CreateBackConnection+0x74
02feebc4 7da456fb rpcrt4!LRPC_CASSOCIATION::ActuallyDoBinding+0x32
02feec3c 7da3843a rpcrt4!LRPC_CASSOCIATION::AllocateCCall+0x190
02feec70 7da38366 rpcrt4!LRPC_BINDING_HANDLE::AllocateCCall+0x1f2
02feec9c 7da37a1c rpcrt4!LRPC_BINDING_HANDLE::NegotiateTransferSyntax+0xd3
02feecb4 7778c956 rpcrt4!I_RpcGetBufferWithObject+0x5b
02feecf8 7778c629 ole32!CRpcChannelBuffer::ClientGetBuffer+0x31c
02feed08 776c0e9e ole32!CRpcChannelBuffer::GetBuffer+0x20
02feed28 776c0f7a ole32!CAptRpcChnl::GetBuffer+0x209
02feed8c 7dac0fda ole32!CCtxComChnl::GetBuffer+0x1e5
02feeda8 7dac0f89 rpcrt4!NdrProxyGetBuffer+0x47
02fef190 776a3717 rpcrt4!NdrClientCall2+0x173
02fef1a8 7778b6e4 ole32!IClassFactory_RemoteCreateInstance_Proxy+0x1c
02fef1c4 776ad8ac ole32!IClassFactory_CreateInstance_Proxy+0x41
02fef24c 776aaf7e ole32!CServerContextActivator::CreateInstance+0x175
02fef28c 776ad9b6 ole32!ActivationPropertiesIn::DelegateCreateInstance+0xf7
02fef2e0 776ad92d ole32!CApartmentActivator::CreateInstance+0x110
02fef300 776acb27 ole32!CProcessActivator::CCICallback+0x6d
02fef320 776acad8 ole32!CProcessActivator::AttemptActivation+0x2c
02fef35c 776ada17 ole32!CProcessActivator::ActivateByContext+0x4f
02fef384 776aaf7e ole32!CProcessActivator::CreateInstance+0x49
02fef3c4 776aaf19 ole32!ActivationPropertiesIn::DelegateCreateInstance+0xf7
02fef614 776aaf7e ole32!CClientContextActivator::CreateInstance+0x8f
02fef654 776ab10f ole32!ActivationPropertiesIn::DelegateCreateInstance+0xf7
02fefe08 776a679a ole32!ICoCreateInstanceEx+0x3f8
02fefe3c 776a6762 ole32!CComActivator::DoCreateInstance+0x6a
02fefe60 776a6963 ole32!CoCreateInstanceEx+0x23
02fefe90 4635a747 ole32!CoCreateInstance+0x3c
02fefec0 4638f691 ieframe!SHCoCreateInstanceAC+0x9e
02feff08 463c167a ieframe!WinList_RegisterPending+0x2c
02feff4c 463ee4b9 ieframe!CTabWindow::_RegisterPendingWindow+0x149
02feffb8 7d4dfe21 ieframe!CTabWindow::_TabWindowThreadProc+0x99
02feffec 00000000 kernel32!BaseThreadStart+0x34&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;El &lt;em&gt;thread&lt;/em&gt; 0 es el &lt;em&gt;thread&lt;/em&gt; principal y aparentemente no está haciendo mucho, salvo esperar que el &lt;em&gt;kernel&lt;/em&gt; le avise que ciertos eventos han ocurrido.&lt;/p&gt;
&lt;p&gt;Sin embargo, el thread 5 sí está haciendo algo y es exactamente lo que yo le había pedido. Crear un tabulador. Esto lo puedo inferir por las llamadas a las funciones con nombres acordes, como se puede apreciar ahora&lt;/p&gt;
&lt;table class="" style="BORDER-RIGHT:1px solid;BORDER-TOP:1px solid;BORDER-LEFT:1px solid;WIDTH:100%;BORDER-BOTTOM:1px solid;"&gt;

&lt;tr&gt;
&lt;td class="" style="BACKGROUND-COLOR:#339933;"&gt;&lt;pre&gt;&lt;span style="COLOR:#ffffff;"&gt;&amp;lt;cortado ...&amp;gt;&lt;/span&gt;&lt;span style="COLOR:#ffffff;"&gt;
02feff4c 463ee4b9 &lt;strong&gt;ieframe!CTabWindow::_RegisterPendingWindow&lt;/strong&gt;+0x149
02feffb8 7d4dfe21 &lt;strong&gt;ieframe!CTabWindow::_TabWindowThreadProc&lt;/strong&gt;+0x99
02feffec 00000000 kernel32!BaseThreadStart+0x34&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;Ok, tenemos el &lt;em&gt;thread&lt;/em&gt; que crea el tabulador. ¿qué más?&lt;/p&gt;
&lt;p&gt;Mirando el &lt;em&gt;stack&lt;/em&gt;, se puede observar creación de objetos COM, posiblemente una creación de contexto de COM o una reutilización de uno existente (no estoy del todo seguro de cual opción), una llamada RPC, interacción con el sub-sistema de Windows (kernel32.dll) y el &lt;em&gt;kernel&lt;/em&gt; (ntdll.dll).&lt;/p&gt;
&lt;p&gt;A diferencia de una revisión de aplicaciones como asp.net o asp tradicional, donde uno espera encontrar código del cliente que no está optimizado y que consume recursos, en esta oportunidad no había código de terceros. El camino se veía difícil.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Golpes de suerte&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Con dos sucesivos golpes de suerte logré dar con el problema, pero jamás podría haberlo detectado sin un post de Mark Russinovich, donde él experimentó un problema similar. El primer golpe de suerte fue elegir alguna función que pareciese sospechosa y luego, &lt;a href="http://www.live.com/"&gt;&lt;em&gt;live&lt;/em&gt;ar&lt;/a&gt; en internet. La función elegida fue &lt;em&gt;GetMachineAccountSid&lt;/em&gt; y la búsqueda retornó este post en primera opción.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/markrussinovich/archive/2006/08/31/453100.aspx"&gt;http://blogs.technet.com/markrussinovich/archive/2006/08/31/453100.aspx&lt;/a&gt;&lt;br /&gt;The Case of the Process Startup Delays &lt;/p&gt;
&lt;p&gt;Con ese título del post, claramente estábamos enfrentando el mismo problema. Eso sí, la diferencia es que Mark sabe reconocer el problema, pero uno debe apelar a la suerte y a los buscadores de internet. &lt;img src="http://msmvps.com/emoticons/emotion-1.gif" alt="Smile" /&gt;&lt;/p&gt;
&lt;p&gt;Haciendo pruebas similares a las del post mencionado, obtuve respuestas similares.&lt;/p&gt;
&lt;p&gt;&lt;img height="112" src="http://msmvps.com/blogs/pmackay/post32/32-02b.png" width="583" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Bien. Traté de atacharme a lsass.exe (&lt;em&gt;local security authority subsystem&lt;/em&gt;) con nefastos resultados. Una vez atachado windbg a lsass, hice una mala maniobra y windbg dejó de responder, haciendo que el sistema quedase medianamente bloqueado (respondía muy lento) ya que muchos procesos depende de lsass.exe. Como no hubo más opción que matar windbg, esto traería como consecuencia que el proceso que se estaba debugueando también moriría. Y si muere lsass.exe, el sistema operativo te pide amablemente reiniciar, con una pantalla similar a la pantalla del virus que atacaba XP antes de SP2 y que te daba 48 segundos para cerrar todo.&lt;/p&gt;
&lt;p&gt;La consecuencia.&lt;/p&gt;
&lt;p&gt;&lt;img height="165" src="http://msmvps.com/blogs/pmackay/post32/32-03b.png" width="374" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Como dirían en algunos programas de televisión; &amp;quot;niños, no traten de hacer esto en casa,&amp;quot; o mejor dicho, no lo hagan mientras visitan a un cliente y deben trabajar con su equipo.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Resolución&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A diferencia del post de Mark, en donde el causante del problema era Defender, en este caso no había un tercer involucrado que remover del sistema.&lt;/p&gt;
&lt;p&gt;La solución no fue la más elegante, pero no tuve más alternativa que ejecutar Internet Explorer en el contexto de un usuario local de la máquina, para así evitar que se trate de obtener información desde el dominio, el cual no puede ser alcanzado.&lt;/p&gt;
&lt;p&gt;Lamentablemente esto trajo como consecuencia que no pudiese accesar a mi historial ni favoritos. Espero que cuando logre conectarme al dominio se acaben los problemas.&lt;/p&gt;
&lt;p&gt;Saludos,&lt;br /&gt;Patrick&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1452044" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/pmackay/archive/tags/Windows+y+Microsoft/default.aspx">Windows y Microsoft</category><category domain="http://msmvps.com/blogs/pmackay/archive/tags/Casos/default.aspx">Casos</category></item><item><title>Signos vitales de un servidor: Parte III (disco)</title><link>http://msmvps.com/blogs/pmackay/archive/2008/01/04/post31.aspx</link><pubDate>Fri, 04 Jan 2008 03:38:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1436141</guid><dc:creator>pmackay</dc:creator><slash:comments>0</slash:comments><comments>http://msmvps.com/blogs/pmackay/archive/2008/01/04/post31.aspx#comments</comments><description>&lt;p&gt;&lt;span style="FONT-SIZE:12pt;COLOR:#ffffff;FONT-FAMILY:Calibri;BACKGROUND-COLOR:#008000;"&gt;Después&lt;/span&gt;&lt;font face="Calibri"&gt;&lt;font style="FONT-SIZE:12pt;"&gt; de unos días de descanso debido a las fiestas ampliamente conocidas, continuamos con la tercera entrega de la serie de monitoreo de signos vitales de un servidor, en la cual presentaremos la información necesaria para detectar problemas de rendimiento en las unidades lógicas de disco de un servidor.&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Si bien es posible determinar problemas en unidades físicas, las diferentes configuraciones físicas de arreglos RAID 0, 1, 5, 1+0 y 0+1 y la creación posterior de unidades lógicas en el arreglo, hace muy difícil, si es que no imposible, el determinar si es o no un disco físico específico. &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Antes de comenzar, hago un mini corte para recomendar este link de una presentación de David Solomon sobre cómo maneja la memoria Windows y como hacer un troubleshooting básico de los problemas. Además, se da tiempo de romper algunos mitos. Definitivamente un video imperdible. Está en inglés y dura 1 hora y 37 minutos.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;a href="http://www.microsoft.com/uk/technet/itsshowtime/sessionh.aspx?videoid=64"&gt;http://www.microsoft.com/uk/technet/itsshowtime/sessionh.aspx?videoid=64&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Diferentes caminos&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Para la verificación de los contadores de disco, existen dos caminos conocidos. Uno de ellos el difícil y otro mucho más simple y agnóstico del hardware.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;El primer camino, el cual NO veremos aquí corresponde a obtener información de los IOs de los discos, calcular la cantidad de operaciones de lectura y escritura que se realizan por cada tipo de RAID, la cantidad de discos físicos (ejes) involucrados en el RAID y hacer una cantidad importantes de cálculos y asumir con poca certeza algunas constantes o valores.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;El segundo camino, mucho más simple, es agnóstico del tipo de RAID, la cantidad de discos y otras variables. ¿Qué es lo que mide? muy simple y básico:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;em&gt;¿Cuánto tiempo se demora el sistema de discos en realizar una operación de escritura o lectura?&lt;/em&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Si se demora &amp;quot;mucho,&amp;quot; hay un problema. Si se demora &amp;quot;poco,&amp;quot; estamos bien. Si tienes picos elevados constantes, podemos estar en presencia de algún inconveniente o escasez de capacidad de procesamiento.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Además de la información relacionada con escrituras y lecturas, se debe complementar con información general del disco como el porcentaje de tiempo disponible y largo de la cola de requerimientos.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Veamos los contadores y contra qué compararlos, es decir, que es &amp;quot;bueno&amp;quot; y &amp;quot;malo.&amp;quot;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Nota: &lt;em&gt;Antes de comenzar aclaro que cuando digo disco &amp;quot;malo,&amp;quot; no estoy mencionando que el disco está malo físicamente o que presenta alguna falla sino que realmente me refiero a que el disco no responde de acuerdo a lo que es espera de él, generalmente producto de una tasa muy elevada de requerimientos.&lt;/em&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Contadores&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Los contadores a medir del objeto Logical Disk, para la instancia específica (c:, d:, etc.), son los siguientes:&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Avg Disk Sec/read: milisegundos en que una operación de lectura es llevada a cabo.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Avg disk Sec/write: milisegundos en que una operación de escritura es llevada a cabo.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;% Idle time: porcentaje de tiempo que el disco está desocupado.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Avg disk queue length: largo promedio de la cola de requerimientos del disco&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Current disk queue length: largo actual de la cola de requerimientos del disco&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;¿Contra que los comparamos?&lt;/strong&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Los dos primeros contadores se comparan contra la misma tabla de valores, la cual despliego a continuación:&lt;/p&gt;
&lt;table class="" style="BORDER-RIGHT:1px solid;BORDER-TOP:1px solid;BORDER-LEFT:1px solid;WIDTH:100%;BORDER-BOTTOM:1px solid;"&gt;

&lt;tr&gt;
&lt;td class="" style="BACKGROUND-COLOR:#92d050;"&gt;&lt;span style="FONT-SIZE:12pt;COLOR:#ffffff;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Valor medido&lt;/strong&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td class="" style="BACKGROUND-COLOR:#92d050;"&gt;&lt;span style="FONT-SIZE:12pt;COLOR:#ffffff;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Significado&lt;/strong&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;entre 1 milisegundo y 15 milisegundos&lt;/span&gt;&lt;/td&gt;
&lt;td class=""&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Perfecto estado&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;entre 16 milisegundos y 25 milisegundos&lt;/span&gt;&lt;/td&gt;
&lt;td class=""&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Se debe monitorear&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;más de 25 milisegundos&lt;/span&gt;&lt;/td&gt;
&lt;td class=""&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Disco degradado&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Se deben considerar valores promedios. Es esperable que un disco tenga picos por sobre los 25 milisegundos pero el valor promedio debe ser bajo.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Nota: &lt;em&gt;Si tienes un storage con caché de escritura, deberás ser más estricto en las comparaciones y reducir un poco los valores. Esto se debe a que el caché de escritura mejora sustancialmente el rendimiento. Si antes 15 ms era el tope para considerar el valor como perfecto, entonces si mides 15 ms y tienes caché habilitado, no estarás dentro del grupo de perfecto estado sino que el rendimiento será medio y deberás monitorear la actividad.&lt;/em&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Anécdota: El valor más alto que he presenciado en algunos casos ha sido de más de 900 milisegundos. Por supuesto, el servicio que se estaba exponiendo estaba severamente afectado, con tiempos de respuesta muy bajos.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;El contador del tiempo porcentaje de tiempo disponible es simple también. Más de 50%, perfecto estado. Entre 20% y 50%, se deberá monitorear y menor a 20%, el disco está degradado.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Por último, para los contadores de largo de cola de requerimientos promedio y actual, estos dos valores se comparan y calculan de la misma forma. Si la cantidad de discos físicos que componen el arreglo de discos es conocida, se deberá comparar contra el valor medido menos la cantidad de discos y dividirlo por dos. &lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Por ejemplo: Si el valor medido del largo promedio de la cola de requerimientos es 25 y tengo 10 discos en el arreglo, la formula nos retorna: (25-10)/2 = 7,5.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Este valor es menor a 1, el rendimiento es excelente. Entre 1 y 3, se deberá monitorear. Mayor a 3, crítico o degradado.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Por supuesto, la formula presenta inconvenientes cuando los valores medidos son menores a la cantidad de discos, pero en ese caso el disco claramente no tiene problemas.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;¿Qué sucede si no conozco la cantidad de discos? y bueno, en ese caso se recomienda dividir por 2 el valor medido en el contador y aplicar la misma regla de comparación. Entendemos que &lt;strong&gt;no&lt;/strong&gt; es un valor fidedigno, pero tampoco es &amp;quot;tan errado.&amp;quot; Para el mismo ejemplo, 25/2&amp;nbsp; es 12,5, un valor mayor a 7,5, pero igual de malo de acuerdo a el parámetro de comparación.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Como pueden ver, monitorear un disco es muy simple. Si no responde en tiempos breves, claramente le estamos pidiendo más de lo que puede dar.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Queda pendiente una o dos entregas más de signos vitales, las que llegarán espero durante este mes.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Saludos,&lt;br /&gt;Patrick&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1436141" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/pmackay/archive/tags/Tips/default.aspx">Tips</category><category domain="http://msmvps.com/blogs/pmackay/archive/tags/Windows+y+Microsoft/default.aspx">Windows y Microsoft</category></item><item><title>Traza de asp.net y el consumo de memoria</title><link>http://msmvps.com/blogs/pmackay/archive/2007/12/18/post30.aspx</link><pubDate>Tue, 18 Dec 2007 02:24:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1402647</guid><dc:creator>pmackay</dc:creator><slash:comments>6</slash:comments><comments>http://msmvps.com/blogs/pmackay/archive/2007/12/18/post30.aspx#comments</comments><description>&lt;p&gt;&lt;span style="FONT-SIZE:12pt;COLOR:#ffffff;FONT-FAMILY:Calibri;BACKGROUND-COLOR:#008000;"&gt;El&lt;/span&gt;&lt;font face="Calibri"&gt;&lt;font style="FONT-SIZE:12pt;"&gt; siguiente caso a presentar está relacionado con el alto consumo de memoria de una aplicación. Como el título lo dice, está relacionado con el uso de la traza de asp.net (trace en &lt;em&gt;web.config&lt;/em&gt;.)&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;El escenario era similar a lo descrito ahora. La aplicación analizada empezaba a consumir memoria y aunque tenía momentos donde la liberaba, la impresión general era que en el largo plazo, siempre subía. Este es un típico comportamiento de un &lt;em&gt;memory leak&lt;/em&gt; o pérdida de memoria; la tendencia al alza, aunque con momentos donde baja un poco.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Como ya es tradición, un &lt;em&gt;dump&lt;/em&gt; del proceso y mi amigo &lt;a href="http://www.microsoft.com/whdc/devtools/debugging/default.mspx"&gt;Debugging Tool For Windows&lt;/a&gt; nos darían las pistas necesarias. También nos apoyamos en performance monitor, pero hay veces que ya sabes que es una pérdida de memoria y éste no te dirá mucho más de lo que ya sabes.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Con el dump en mis manos, hacemos una revisión del proceso afectado y el estado de la memoria virtual del éste.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Recolección de información general&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Tamaño del dump: ~300 MB. No es muy grande, pero tampoco es descartable. Tradicionalmente se espera a que la memoria privada del proceso llegue al menos hasta 500 MB para declararlo como sospechoso.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Información del proceso:&lt;/p&gt;
&lt;table class="MsoTableGrid" style="BORDER-RIGHT:medium none;BORDER-TOP:medium none;BORDER-LEFT:medium none;BORDER-BOTTOM:medium none;BORDER-COLLAPSE:collapse;" cellspacing="0" cellpadding="0" class="MsoTableGrid"&gt;

&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:black 1pt solid;PADDING-RIGHT:5.4pt;BORDER-TOP:black 1pt solid;PADDING-LEFT:5.4pt;BACKGROUND:#92d050;PADDING-BOTTOM:0cm;BORDER-LEFT:black 1pt solid;WIDTH:727pt;PADDING-TOP:0cm;BORDER-BOTTOM:black 1pt solid;"&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#1000a0;FONT-FAMILY:Courier New;"&gt;System Uptime: 180 days 15:52:41.140&lt;br /&gt;Process Uptime: 0 days 2:08:23.000&lt;br /&gt;Kernel time: 0 days 0:00:13.000&lt;br /&gt;User time: 0 days 0:08:48.000 &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;El sistema operativo lleva corriendo 180 días sin reiniciarse. El proceso en cuestión lleva del orden de 2 horas y 8 minutos corriendo y que ha consumido 13 segundos en modo privilegiado (&lt;em&gt;kernel&lt;/em&gt;) y 8 minutos y 48 segundos en modo usuario. 
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Con 8 minutos de procesamiento ya llegó a 300 MB. Interesante.&lt;/p&gt;
&lt;table class="" style="WIDTH:100%;"&gt;

&lt;tr&gt;
&lt;td class=""&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;El estado de la memoria virtual concuerda con el tamaño del dump, reflejado gráficamente en la imagen de la derecha, la cual pueden pinchar para agrandar. 
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Efectivamente hay aproximadamente 300 MB de memoria virtual, de los cuales casi 190 son de memoria manejada.&lt;/p&gt;&lt;/td&gt;
&lt;td class=""&gt;&lt;a href="http://msmvps.com/blogs/pmackay/post30/30-01b.png" target="_blank"&gt;&lt;img style="BORDER-TOP-WIDTH:0px;BORDER-LEFT-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-RIGHT-WIDTH:0px;" height="152" src="http://msmvps.com/blogs/pmackay/post30/30-01s.png" width="150" alt="" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Memoria manejada&lt;/strong&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Haciendo una revisión de los &lt;em&gt;heaps&lt;/em&gt; del GC, obtenemos la información de la siguiente lista. El servidor tiene 4 procesadores por lo que se crean cuatro &lt;em&gt;heaps&lt;/em&gt; del GC, cada uno con sus propias generaciones, &lt;em&gt;heaps&lt;/em&gt; efímeros y &lt;em&gt;heaps&lt;/em&gt; de objetos grandes.&lt;/p&gt;
&lt;table class="MsoTableGrid" style="BORDER-RIGHT:medium none;BORDER-TOP:medium none;BORDER-LEFT:medium none;BORDER-BOTTOM:medium none;BORDER-COLLAPSE:collapse;" cellspacing="0" cellpadding="0" class="MsoTableGrid"&gt;

&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:black 1pt solid;PADDING-RIGHT:5.4pt;BORDER-TOP:black 1pt solid;PADDING-LEFT:5.4pt;BACKGROUND:#92d050;PADDING-BOTTOM:0cm;BORDER-LEFT:black 1pt solid;WIDTH:727pt;PADDING-TOP:0cm;BORDER-BOTTOM:black 1pt solid;"&gt;&lt;span style="FONT-SIZE:8pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;, Courier, monospace;BACKGROUND-COLOR:#92d050;"&gt;Number of GC Heaps: 4&lt;br /&gt;------------------------------&lt;br /&gt;Heap 0 (0x000d01c8)&lt;br /&gt;generation 0 starts at 0x121135c8&lt;br /&gt;generation 1 starts at 0x12109a44&lt;br /&gt;generation 2 starts at 0x102d0030&lt;br /&gt;ephemeral segment allocation context: none&lt;br /&gt;segment begin allocated size reserved&lt;br /&gt;0x102d0000 0x102d0030 0x121135d4 0x01e435a4(31,733,156) 0x00d79000&lt;br /&gt;Large object heap starts at 0x202d0030&lt;br /&gt;segment begin allocated size reserved&lt;br /&gt;0x202d0000 0x202d0030 0x205d2168 0x00302138(3,154,232) 0x00cdd000&lt;br /&gt;Heap Size 0x2245770(35,936,112)&lt;br /&gt;------------------------------&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:8pt;COLOR:#ffffff;FONT-FAMILY:&amp;#39;Courier New&amp;#39;, Courier, monospace;BACKGROUND-COLOR:#92d050;"&gt;Heap 1 (0x000d08d8)&lt;br /&gt;generation 0 starts at 0x16009a28&lt;br /&gt;generation 1 starts at 0x15eaacac&lt;br /&gt;generation 2 starts at 0x142d0030&lt;br /&gt;ephemeral segment allocation context: none&lt;br /&gt;segment begin allocated size reserved&lt;br /&gt;0x142d0000 0x142d0030 0x16009a34 0x01d39a04(30,644,740) 0x014c7000&lt;br /&gt;Large object heap starts at 0x212d0030&lt;br /&gt;segment begin allocated size reserved&lt;br /&gt;0x212d0000 0x212d0030 0x21449a38 0x00179a08(1,546,760) 0x00e66000&lt;br /&gt;Heap Size 0x1f2b4a0(32,683,168)&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:8pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;, Courier, monospace;BACKGROUND-COLOR:#92d050;"&gt;------------------------------&lt;br /&gt;Heap 2 (0x000d13d8)&lt;br /&gt;generation 0 starts at 0x24461404&lt;br /&gt;generation 1 starts at 0x243e6e2c&lt;br /&gt;generation 2 starts at 0x182d0030&lt;br /&gt;ephemeral segment allocation context: none&lt;br /&gt;segment begin allocated size reserved&lt;br /&gt;0x182d0000 0x182d0030 0x1998c7dc 0x016bc7ac(23,840,684) 0x028ef000&lt;br /&gt;0x242d0000 0x242d0030 0x24461410 0x001913e0(1,643,488) 0x033c4000&lt;br /&gt;Large object heap starts at 0x2a2d0030&lt;br /&gt;segment begin allocated size reserved&lt;br /&gt;0x2a2d0000 0x2a2d0030 0x2a2d0030 0x00000000(0) 0x047df000&lt;br /&gt;Heap Size 0x198fb8c(26,803,084)&lt;br /&gt;------------------------------&lt;/span&gt; &lt;span style="FONT-SIZE:8pt;COLOR:#ffffff;FONT-FAMILY:&amp;#39;Courier New&amp;#39;, Courier, monospace;BACKGROUND-COLOR:#92d050;"&gt;&lt;br /&gt;Heap 3 (0x000d1ca0)&lt;br /&gt;generation 0 starts at 0x087954cc&lt;br /&gt;generation 1 starts at 0x083dd820&lt;br /&gt;generation 2 starts at 0x1c2d0030&lt;br /&gt;ephemeral segment allocation context: none&lt;br /&gt;segment begin allocated size reserved&lt;br /&gt;0x1c2d0000 0x1c2d0030 0x1df48b8c 0x01c78b5c(29,854,556) 0x02310000&lt;br /&gt;0x08330000 0x08330030 0x087954d8 0x004654a8(4,609,192) 0x01fff000&lt;br /&gt;Large object heap starts at 0x232d0030&lt;br /&gt;segment begin allocated size reserved&lt;br /&gt;0x232d0000 0x232d0030 0x2344ed50 0x0017ed20(1,568,032) 0x00e61000&lt;br /&gt;0x0edc0000 0x0edc0030 0x0f195f40 0x003d5f10(4,022,032) 0x00c2a000&lt;br /&gt;Heap Size 0x277ac50(41,397,328)&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:8pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;------------------------------&lt;br /&gt;Reserved segments:&lt;br /&gt;------------------------------&lt;br /&gt;GC Heap Size 0x827b3ec(136,819,692)&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;De esta información se puede ver que hay muchos objetos en generación 2, lo que significa que hay objetos que no se han liberado y han ido envejeciendo más de lo necesario.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;¿Qué hay en la memoria?&lt;/strong&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Haciendo un vaciado estadístico de los objetos, utilizando &lt;a href="http://www.microsoft.com/whdc/devtools/debugging/default.mspx"&gt;Debugging Tool For Windows&lt;/a&gt; y sos, obtenemos un listado como el de a continuación, donde se ha eliminado parte del comienzo y sólo se ha dejado el final, que contiene la información relevante para el caso.&lt;/p&gt;
&lt;table class="MsoTableGrid" style="BORDER-RIGHT:medium none;BORDER-TOP:medium none;BORDER-LEFT:medium none;BORDER-BOTTOM:medium none;BORDER-COLLAPSE:collapse;" cellspacing="0" cellpadding="0" class="MsoTableGrid"&gt;

&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:black 1pt solid;PADDING-RIGHT:5.4pt;BORDER-TOP:black 1pt solid;PADDING-LEFT:5.4pt;BACKGROUND:#92d050;PADDING-BOTTOM:0cm;BORDER-LEFT:black 1pt solid;WIDTH:727pt;PADDING-TOP:0cm;BORDER-BOTTOM:black 1pt solid;"&gt;&lt;span style="FONT-SIZE:8pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;, Courier, monospace;BACKGROUND-COLOR:#92d050;"&gt;MT&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Count TotalSize Class Name&lt;br /&gt;&lt;em&gt;.....&amp;lt;recortado por el bien de esta página&amp;gt;...&lt;/em&gt;&lt;br /&gt;0x028665f0 22,807 273,684 System.Xml.Xsl.EndEvent&lt;br /&gt;0x02784adc 14,800 296,000 System.Data.DataRowCollection&lt;br /&gt;0x027844dc 14,800 296,000 System.Data.DataRowBuilder&lt;br /&gt;0x027862d4 14,911 298,220 System.Data.ColumnQueue&lt;br /&gt;0x02782a74 11,824 331,072 System.ComponentModel.CollectionChangeEventHandler&lt;br /&gt;0x0230159c 14,866 356,784 System.Xml.NameTable/Entry&lt;br /&gt;0x02925aec 7,847 408,044 System.Xml.Xsl.XsltCompileContext&lt;br /&gt;0x02926bfc 11,589 417,204 System.Xml.XPath.XPathChildIterator&lt;br /&gt;0x02863d04 8,692 417,216 System.Xml.XPath.ChildrenQuery&lt;br /&gt;0x027846d4 14,800 473,600 System.Data.RecordManager&lt;br /&gt;0x0278001c 14,800 473,600 System.Data.ConstraintCollection&lt;br /&gt;0x027842e4 14,913 477,216 System.ComponentModel.PropertyDescriptorCollection&lt;br /&gt;0x0280cddc 16,754 670,160 System.Xml.XPath.XPathWhitespace&lt;br /&gt;0x0280c924 10,044 682,992 System.Xml.XPath.XPathElement&lt;br /&gt;0x02866564 22,807 729,824 System.Xml.Xsl.BeginEvent&lt;br /&gt;0x0252ebe4 14,800 769,600 System.Data.DataColumnCollection&lt;br /&gt;0x79bda488 14,813 888,780 System.Threading.ReaderWriterLock&lt;br /&gt;0x79bab93c 17,498 909,896 System.Collections.Hashtable&lt;br /&gt;0x02923770 28,877 924,064 System.Xml.DocumentXPathNavigator&lt;br /&gt;0x027882e4 40,203 964,872 System.Data.Common.StringStorage&lt;br /&gt;0x0280cba4 21,157 1,015,536 System.Xml.XPath.XPathAttribute&lt;br /&gt;0x0278489c 29,600 1,184,000 System.Data.DataRelationCollection/DataTableRelationCollection&lt;br /&gt;0x01ba2c28 17,561 2,839,896 System.Collections.Hashtable/bucket[]&lt;br /&gt;0x0252e4b0 14,800 3,433,600 System.Data.DataTable&lt;br /&gt;0x79ba2ee4 145,618 3,494,832 System.Collections.ArrayList&lt;br /&gt;0x0278670c 54,976 3,518,464 System.Data.DataColumnPropertyDescriptor&lt;br /&gt;0x01ba2964 24,879 5,024,760 System.Int32[]&lt;br /&gt;&lt;span style="COLOR:#ffffff;"&gt;0x0278513c 136,364 5,454,560 System.Data.DataRow&lt;br /&gt;0x0252f5d0 54,760 7,009,280 System.Data.DataColumn&lt;br /&gt;&lt;/span&gt;0x01ba26b0 1,262 8,513,840 System.Byte[]&lt;br /&gt;0x000cff48 2,829 14,897,824 Free&lt;br /&gt;&lt;span style="COLOR:#ffffff;"&gt;0x79b94638 238,884 23,296,388 System.String&lt;br /&gt;0x01ba209c 235,235 40,966,392 System.Object[]&lt;br /&gt;&lt;/span&gt;Total 1,509,853 objects, Total size: 136,798,976&lt;br /&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Existe un poco más de 1,5 millones de objetos en memoria, que consumen cerca de 136 MB, similar al resultado entregado en la lista anterior.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;De esos 1,5 millones de objetos, existe una gran cantidad de &lt;em&gt;strings&lt;/em&gt; y arreglos de objeto, como también de filas de datos y columnas de datos. Este comportamiento se presenta cuando se han creado Datasets y no se han liberado.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Un &lt;em&gt;DataSet&lt;/em&gt; contiene filas y columnas, y en cada celda encontramos objetos de los tipos básicos como strings, enteros, decimales, objetos, etc. Por lo tanto, estos objetos que se ven al final no viven solos sino que están referenciados desde otro objeto, como podría ser un &lt;em&gt;dataset&lt;/em&gt;. No significa que todos estén referenciados, pero con 136 mil filas (&lt;em&gt;DataRow&lt;/em&gt;) y 54 mil columnas (&lt;em&gt;DataColumn&lt;/em&gt;), varios de esos miles de objetos si lo están.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;¿Cuantos &lt;/strong&gt;&lt;em&gt;&lt;strong&gt;DataSets&lt;/strong&gt;&lt;/em&gt;&lt;strong&gt; hay?&lt;/strong&gt;&lt;/p&gt;
&lt;table class="MsoTableGrid" style="BORDER-RIGHT:medium none;BORDER-TOP:medium none;BORDER-LEFT:medium none;BORDER-BOTTOM:medium none;BORDER-COLLAPSE:collapse;" cellspacing="0" cellpadding="0" class="MsoTableGrid"&gt;

&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:black 1pt solid;PADDING-RIGHT:5.4pt;BORDER-TOP:black 1pt solid;PADDING-LEFT:5.4pt;BACKGROUND:#92d050;PADDING-BOTTOM:0cm;BORDER-LEFT:black 1pt solid;WIDTH:727pt;PADDING-TOP:0cm;BORDER-BOTTOM:black 1pt solid;"&gt;&lt;span style="FONT-SIZE:8pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;, Courier, monospace;BACKGROUND-COLOR:#92d050;"&gt;MT&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Count TotalSize Class Name&lt;br /&gt;0x0252ce84 1,597 127,760 System.Data.DataSet&lt;br /&gt;&lt;span style="COLOR:#ffffff;"&gt;Total 1,597 objects, Total size: 127,760&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Bueno, tomemos uno al azar y veamos donde nos lleva. Elegimos el objeto en la posición de memoria 0x0834d148.&lt;/p&gt;
&lt;table class="MsoTableGrid" style="BORDER-RIGHT:medium none;BORDER-TOP:medium none;BORDER-LEFT:medium none;BORDER-BOTTOM:medium none;BORDER-COLLAPSE:collapse;" cellspacing="0" cellpadding="0" class="MsoTableGrid"&gt;

&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:black 1pt solid;PADDING-RIGHT:5.4pt;BORDER-TOP:black 1pt solid;PADDING-LEFT:5.4pt;BACKGROUND:#92d050;PADDING-BOTTOM:0cm;BORDER-LEFT:black 1pt solid;WIDTH:727pt;PADDING-TOP:0cm;BORDER-BOTTOM:black 1pt solid;"&gt;&lt;span style="FONT-SIZE:8pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;, Courier, monospace;BACKGROUND-COLOR:#92d050;"&gt;Name: System.Data.DataSet&lt;br /&gt;MethodTable 0x0252ce84&lt;br /&gt;EEClass 0x0275b43c&lt;br /&gt;Size 80(0x50) bytes&lt;br /&gt;GC Generation: 2&lt;br /&gt;mdToken: 0x0200003b (c:\windows\assembly\gac\system.data\1.0.5000.0__b77a5c561934e089\system.data.dll)&lt;br /&gt;FieldDesc*: 0x0252c4b4&lt;br /&gt;MT Field Offset Type Attr Value Name&lt;br /&gt;0x0252c23c 0x4000583 0x4 CLASS instance 0x00000000 site&lt;br /&gt;0x0252c23c 0x4000584 0x8 CLASS instance 0x00000000 events&lt;br /&gt;0x0252c23c 0x4000582 0 CLASS shared static EventDisposed&lt;br /&gt;&amp;gt;&amp;gt; Domain:Value 0x000c4ac8:NotInit 0x00138380:0x1c331c58 &amp;lt;&amp;lt;&lt;br /&gt;0x0252ce84 0x40003d3 0xc CLASS instance 0x15cee704 defaultViewManager&lt;br /&gt;0x0252ce84 0x40003d4 0x10 CLASS instance 0x0834d198 tableCollection&lt;br /&gt;0x0252ce84 0x40003d5 0x14 CLASS instance 0x0834d220 relationCollection&lt;br /&gt;0x0252ce84 0x40003d6 0x18 CLASS instance 0x00000000 extendedProperties&lt;br /&gt;&lt;span style="COLOR:#ffffff;"&gt;0x0252ce84 0x40003d7 0x1c CLASS instance 0x1c331c30 dataSetName&lt;/span&gt;&lt;br /&gt;0x0252ce84 0x40003d8 0x20 CLASS instance 0x102d0224 _datasetPrefix&lt;br /&gt;0x0252ce84 0x40003d9 0x24 CLASS instance 0x102d0224 namespaceURI&lt;br /&gt;0x0252ce84 0x40003da 0x40 System.Boolean instance 0 caseSensitive&lt;br /&gt;0x0252ce84 0x40003db 0x28 CLASS instance 0x1c2e69c8 culture&lt;br /&gt;0x0252ce84 0x40003dc 0x41 System.Boolean instance 1 enforceConstraints&lt;br /&gt;0x0252ce84 0x40003dd 0x42 System.Boolean instance 0 fInReadXml&lt;br /&gt;0x0252ce84 0x40003de 0x43 System.Boolean instance 0 fInLoadDiffgram&lt;br /&gt;0x0252ce84 0x40003df 0x44 System.Boolean instance 0 fTopLevelTable&lt;br /&gt;0x0252ce84 0x40003e0 0x45 System.Boolean instance 0 fInitInProgress&lt;br /&gt;0x0252ce84 0x40003e1 0x46 System.Boolean instance 1 fEnableCascading&lt;br /&gt;0x0252ce84 0x40003e2 0x47 System.Boolean instance 0 fIsSchemaLoading&lt;br /&gt;0x0252ce84 0x40003e3 0x2c CLASS instance 0x00000000 rowDiffId&lt;br /&gt;0x0252ce84 0x40003e4 0x48 System.Boolean instance 0 fBoundToDocument&lt;br /&gt;0x0252ce84 0x40003e5 0x30 CLASS instance 0x00000000 onPropertyChangingDelegate&lt;br /&gt;0x0252ce84 0x40003e6 0x34 CLASS instance 0x00000000 onMergeFailed&lt;br /&gt;0x0252ce84 0x40003e7 0x38 CLASS instance 0x00000000 onDataRowCreated&lt;br /&gt;0x0252ce84 0x40003e8 0x3c CLASS instance 0x00000000 onClearFunctionCalled&lt;br /&gt;0x0252ce84 0x40003e9 0 CLASS shared static zeroTables&lt;br /&gt;&amp;gt;&amp;gt; Domain:Value 0x000c4ac8:NotInit 0x00138380:0x1c331c20 &amp;lt;&amp;lt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Mmm, nada más que un dataset. No se si podría haber encontrado otra cosa &lt;img src="http://msmvps.com/emoticons/emotion-1.gif" alt="Smile" /&gt;. Veamos el nombre de éste, en la posición 0x1c331c30 (línea blanca arriba).&lt;/p&gt;
&lt;table class="MsoTableGrid" style="BORDER-RIGHT:medium none;BORDER-TOP:medium none;BORDER-LEFT:medium none;BORDER-BOTTOM:medium none;BORDER-COLLAPSE:collapse;" cellspacing="0" cellpadding="0" class="MsoTableGrid"&gt;

&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:black 1pt solid;PADDING-RIGHT:5.4pt;BORDER-TOP:black 1pt solid;PADDING-LEFT:5.4pt;BACKGROUND:#92d050;PADDING-BOTTOM:0cm;BORDER-LEFT:black 1pt solid;WIDTH:727pt;PADDING-TOP:0cm;BORDER-BOTTOM:black 1pt solid;"&gt;&lt;span style="FONT-SIZE:8pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;, Courier, monospace;BACKGROUND-COLOR:#92d050;"&gt;String: NewDataSet&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;img src="http://msmvps.com/emoticons/emotion-7.gif" alt="Tongue Tied" /&gt;. El nombre genérico no da pistas para encontrar alguna parte del código que lo esté creando. Vemos entonces quién lo está apuntando.&lt;/p&gt;
&lt;table class="MsoTableGrid" style="BORDER-RIGHT:medium none;BORDER-TOP:medium none;BORDER-LEFT:medium none;BORDER-BOTTOM:medium none;BORDER-COLLAPSE:collapse;" cellspacing="0" cellpadding="0" class="MsoTableGrid"&gt;

&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:black 1pt solid;PADDING-RIGHT:5.4pt;BORDER-TOP:black 1pt solid;PADDING-LEFT:5.4pt;BACKGROUND:#92d050;PADDING-BOTTOM:0cm;BORDER-LEFT:black 1pt solid;WIDTH:727pt;PADDING-TOP:0cm;BORDER-BOTTOM:black 1pt solid;"&gt;&lt;span style="FONT-SIZE:8pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;, Courier, monospace;BACKGROUND-COLOR:#92d050;"&gt;Scan Thread 10 (0x1cac)&lt;br /&gt;Scan Thread 16 (0xa00)&lt;br /&gt;Scan Thread 17 (0x1908)&lt;br /&gt;Scan Thread 5 (0xa0c)&lt;br /&gt;Scan Thread 4 (0x1dcc)&lt;br /&gt;Scan Thread 19 (0x1a6c)&lt;br /&gt;Scan Thread 3 (0x1584)&lt;br /&gt;Scan Thread 2 (0x444)&lt;br /&gt;Scan Thread 20 (0x15f4)&lt;br /&gt;ESP:36ff548:Root:0x1c6b59a8(System.Threading.Thread)-&amp;gt;0x15cecad4(System.Runtime.Remoting.Messaging.IllogicalCallContext)-&amp;gt;0x15cecae0(System.Collections.Hashtable)-&amp;gt;0x15cecb14(System.Collections.Hashtable/bucket[])-&amp;gt;0x15cec81c(System.Web.HttpContext)-&amp;gt;0x15cec608(System.Web.Hosting.ISAPIWorkerRequestInProcForIIS6)-&amp;gt;0x182d81c4(System.Web.HttpWorkerRequest/EndOfSendNotification)-&amp;gt;0x14339e70(System.Web.HttpRuntime)-&amp;gt;&lt;span style="COLOR:#ffffff;"&gt;0x182d7fac(System.Web.Util.Profiler)&lt;/span&gt;-&amp;gt;0x14358454(System.Collections.ArrayList)-&amp;gt;0x1d89d7b0(System.Object[])-&amp;gt;&lt;span style="COLOR:#ffffff;"&gt;0x834d148(System.Data.DataSet)&lt;/span&gt;&lt;br /&gt;Scan Thread 22 (0x1098)&lt;br /&gt;Scan Thread 24 (0xcd8)&lt;br /&gt;&lt;em&gt;.....&amp;lt;recortado por el bien de esta página&amp;gt;...&lt;br /&gt;&lt;/em&gt;Scan Thread 67 (0x1938)&lt;br /&gt;Scan Thread 54 (0x618)&lt;br /&gt;Scan HandleTable 0xc9ec0&lt;br /&gt;Scan HandleTable 0xcd008&lt;br /&gt;Scan HandleTable 0x147008 &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;El &lt;em&gt;thread&lt;/em&gt; 20, que está procesando un requerimiento en la extensión ISAPI de asp.net en IIS6 (&lt;em&gt;System.Web.Hosting.ISAPIWorkerRequestInProcForIIS6&lt;/em&gt;) tiene una referencia fuerte al objeto. Vemos también un &lt;em&gt;HashTable&lt;/em&gt;, el &lt;em&gt;Contexto&lt;/em&gt; y &lt;em&gt;Runtime&lt;/em&gt; de http, los cuales se pueden considerar normales en el ciclo de vida de un requerimiento web.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Sin embargo, hay un invitado especial en esta lista de referencias. Éste es &lt;em&gt;System.Web.Util.Profiler&lt;/em&gt;, del cual no hay mucha información disponible, pero después de examinarlo, ya podemos inferir de quién se trata. Veamos su contenido.&lt;/p&gt;
&lt;table class="MsoTableGrid" style="BORDER-RIGHT:medium none;BORDER-TOP:medium none;BORDER-LEFT:medium none;BORDER-BOTTOM:medium none;BORDER-COLLAPSE:collapse;" cellspacing="0" cellpadding="0" class="MsoTableGrid"&gt;

&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:black 1pt solid;PADDING-RIGHT:5.4pt;BORDER-TOP:black 1pt solid;PADDING-LEFT:5.4pt;BACKGROUND:#92d050;PADDING-BOTTOM:0cm;BORDER-LEFT:black 1pt solid;WIDTH:727pt;PADDING-TOP:0cm;BORDER-BOTTOM:black 1pt solid;"&gt;&lt;span style="FONT-SIZE:8pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;, Courier, monospace;BACKGROUND-COLOR:#92d050;"&gt;Name: System.Web.Util.Profiler&lt;br /&gt;MethodTable 0x021c49d0&lt;br /&gt;EEClass 0x0215912c&lt;br /&gt;Size 28(0x1c) bytes&lt;br /&gt;GC Generation: 2&lt;br /&gt;mdToken: 0x0200029d (c:\windows\assembly\gac\system.web\1.0.5000.0__b03f5f7f11d50a3a\system.web.dll)&lt;br /&gt;FieldDesc*: 0x021c4704&lt;br /&gt;MT Field Offset Type Attr Value Name&lt;br /&gt;0x021c49d0 0x4001076 0x8 &lt;span style="COLOR:#ffffff;"&gt;System.Int32 instance 1478 _requestNum&lt;/span&gt;&lt;br /&gt;0x021c49d0 0x4001077 0xc &lt;span style="COLOR:#ffffff;"&gt;System.Int32 instance 7500 _requestsToProfile&lt;/span&gt;&lt;br /&gt;0x021c49d0 0x4001078 0x4 CLASS instance &lt;span style="COLOR:#ffffff;"&gt;0x14358454&lt;/span&gt; _requests&lt;br /&gt;0x021c49d0 0x4001079 0x14 System.Boolean instance 0 _pageOutput&lt;br /&gt;0x021c49d0 0x400107a 0x15 System.Boolean instance 1 _isEnabled&lt;br /&gt;0x021c49d0 0x400107b 0x16 System.Boolean instance 1 _oldEnabled&lt;br /&gt;0x021c49d0 0x400107c 0x17 System.Boolean instance 0 _localOnly&lt;br /&gt;0x021c49d0 0x400107d 0x10 System.Int32 instance 0 _outputMode&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Recordando las propiedades de la traza de asp.net, podemos ver asombrosas similitudes con las propiedades. Veamos la definición de la traza en el archivo &lt;em&gt;web.config&lt;/em&gt;. La información oficial dice:&lt;/p&gt;
&lt;table class="MsoTableGrid" style="BORDER-RIGHT:medium none;BORDER-TOP:medium none;BORDER-LEFT:medium none;BORDER-BOTTOM:medium none;BORDER-COLLAPSE:collapse;" cellspacing="0" cellpadding="0" class="MsoTableGrid"&gt;

&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:black 1pt solid;PADDING-RIGHT:5.4pt;BORDER-TOP:black 1pt solid;PADDING-LEFT:5.4pt;BACKGROUND:#92d050;PADDING-BOTTOM:0cm;BORDER-LEFT:black 1pt solid;WIDTH:727pt;PADDING-TOP:0cm;BORDER-BOTTOM:black 1pt solid;"&gt;&lt;span style="FONT-SIZE:8pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;, Courier, monospace;BACKGROUND-COLOR:#92d050;"&gt;&amp;lt;trace &lt;br /&gt;enabled=&amp;quot;true|false&amp;quot;&lt;br /&gt;localOnly=&amp;quot;true|false&amp;quot;&lt;br /&gt;pageOutput=&amp;quot;true|false&amp;quot;&lt;br /&gt;requestLimit=&amp;quot;integer&amp;quot; &lt;br /&gt;mostRecent=&amp;quot;true|false&amp;quot;&lt;br /&gt;writeToDiagnosticsTrace=&amp;quot;true|false&amp;quot;&lt;br /&gt;traceMode=&amp;quot;SortByTime|SortByCategory&amp;quot;&lt;br /&gt;/&amp;gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;El &lt;em&gt;dump&lt;/em&gt; dice que la traza estaba habilitada (&lt;em&gt;_isEnabled&lt;/em&gt;), no estaba local (&lt;em&gt;_localOnly&lt;/em&gt;), que tenía marcado para almacenar hasta 7.500 requerimientos (segunda línea blanca) y que habían 1478 almacenados (primera línea blanca). El resto de las propiedades las pueden chequear ustedes. Recordemos que habían 1597 &lt;em&gt;DataSets&lt;/em&gt; en memoria.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;El objeto &lt;em&gt;_requests&lt;/em&gt; es un &lt;em&gt;System.Collections.ArrayList&lt;/em&gt; y los 1478 objetos dentro suman casi la totalidad de memoria manejada, que si bien recordarán, sumaba cerca de 136 MB.&lt;/p&gt;
&lt;table class="MsoTableGrid" style="BORDER-RIGHT:medium none;BORDER-TOP:medium none;BORDER-LEFT:medium none;BORDER-BOTTOM:medium none;BORDER-COLLAPSE:collapse;" cellspacing="0" cellpadding="0" class="MsoTableGrid"&gt;

&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:black 1pt solid;PADDING-RIGHT:5.4pt;BORDER-TOP:black 1pt solid;PADDING-LEFT:5.4pt;BACKGROUND:#92d050;PADDING-BOTTOM:0cm;BORDER-LEFT:black 1pt solid;WIDTH:727pt;PADDING-TOP:0cm;BORDER-BOTTOM:black 1pt solid;"&gt;&lt;span style="FONT-SIZE:8pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;, Courier, monospace;BACKGROUND-COLOR:#92d050;"&gt;sizeof(0x14358454) = 91,258,512 (0x5707e90) bytes (System.Collections.ArrayList) &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Entonces, la condición de memoria elevada, se da en parte porque hay ~90 MB de objetos referenciados por la traza de asp.net. También hay una cantidad de importante de memoria (~70 MB) consumida por dlls y ensamblados (ver la primera imagen.)&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Conclusiones&lt;/strong&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Las conclusiones que se pueden obtener en este caso son:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;No todos las pérdidas de memoria son producto de errores en la codificación.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Si vas a habilitar la traza en producción, recuerda deshabilitarla una vez que termines. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;También, si no vas a poder leer la información de 7500 trazas, configúralo para que almacene menos.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Saludos,&lt;br /&gt;Patrick&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1402647" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/pmackay/archive/tags/Memoria+y+GC/default.aspx">Memoria y GC</category><category domain="http://msmvps.com/blogs/pmackay/archive/tags/.net/default.aspx">.net</category><category domain="http://msmvps.com/blogs/pmackay/archive/tags/Casos/default.aspx">Casos</category></item><item><title>Signos vitales de un servidor: Parte II (procesador)</title><link>http://msmvps.com/blogs/pmackay/archive/2007/12/17/post29.aspx</link><pubDate>Mon, 17 Dec 2007 04:08:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1401057</guid><dc:creator>pmackay</dc:creator><slash:comments>0</slash:comments><comments>http://msmvps.com/blogs/pmackay/archive/2007/12/17/post29.aspx#comments</comments><description>&lt;p&gt;&lt;span style="FONT-SIZE:12pt;COLOR:#ffffff;FONT-FAMILY:Calibri;BACKGROUND-COLOR:#008000;"&gt;Continuando&lt;/span&gt;&lt;font face="Calibri"&gt;&lt;font style="FONT-SIZE:12pt;"&gt; con los signos vitales de un servidor, hoy día veremos en la segunda parte, el procesador.&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;El análisis del procesador es bastante más simple que el de la memoria. Hay dos contadores importantes. Uno de ellos corresponde al uso del procesador, con dos matices especiales; uso del procesador en modo usuario y el otro en modo &lt;em&gt;kernel&lt;/em&gt;. El otro contador corresponde a la cantidad de requerimientos encolados del procesador.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Como ya hemos visto en otros &lt;em&gt;&lt;a href="http://msmvps.com/blogs/pmackay/archive/2007/10/15/post22.aspx" target="_blank"&gt;posts&lt;/a&gt;&lt;/em&gt;, Windows utiliza dos modos de ejecución. Uno de ellos es el modo usuario, donde corren las aplicaciones que nosotros ejecutamos y el otro es el modo &lt;em&gt;Kernel&lt;/em&gt;, en el cual corre el &lt;em&gt;kernel&lt;/em&gt; del sistema operativo.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;¿Por qué es importante esta explicación?&lt;/strong&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Si logramos identificar quién está consumiendo el procesador, podremos inferir y tener mejores pistas para encontrar al culpable del consumo de éste.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Si te preguntas ¿para qué necesitas saber el modo (usuario o &lt;em&gt;kernel) &lt;/em&gt;que está consumiendo el procesador, si mirando el task manager sabrás fácilmente qué aplicación es responsable?&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Bueno. Hay un par de razones. Veamos cada una de ellas.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;1.- &lt;em&gt;Task manager&lt;/em&gt; te dirá la aplicación que está consumiendo el procesador, pero no te dirá más. Solo la aplicación. &lt;em&gt;Perfmon&lt;/em&gt; por otra parte te podrá entregar más información. &lt;em&gt;&lt;a href="http://www.microsoft.com/technet/sysinternals/ProcessesAndThreads/ProcessExplorer.mspx"&gt;Process Explorer&lt;/a&gt;&lt;/em&gt; de &lt;em&gt;Sysinternals&lt;/em&gt; es una excelente herramienta. &lt;br /&gt;2.- &lt;em&gt;Task manager&lt;/em&gt; no muestra siempre el consumo del &lt;em&gt;kernel&lt;/em&gt;.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;El segundo punto no está tan relacionado con aplicaciones, pero vale la pena aclarar que hay ciertas actividades del &lt;em&gt;kernel&lt;/em&gt; que no son cuantificadas por &lt;em&gt;Task Manager&lt;/em&gt;, o son cuantificadas pero no desplegadas. Recordemos que el &lt;em&gt;kernel&lt;/em&gt; corresponde al proceso llamado &lt;em&gt;System&lt;/em&gt;, siempre con el PID 4. Entonces puede parecer que tu sistema tiene bajo uso del procesador, pero el &lt;em&gt;kernel&lt;/em&gt; está trabajando activamente. Para mejores resultados en el despliegue de los recursos consumidos, puedes utilizar &lt;em&gt;&lt;a href="http://www.microsoft.com/technet/sysinternals/ProcessesAndThreads/ProcessExplorer.mspx"&gt;Process Explorer&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Resumiendo&lt;/strong&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Podemos decir que para una aplicación específica:&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;El porcentaje de consumo en modo &lt;em&gt;kernel&lt;/em&gt; corresponde a las actividades que debe realizar el &lt;em&gt;kernel &lt;/em&gt;para cumplir con los requerimientos de la aplicación, como por ejemplo, trabajar con archivos, mover memoria, escribir en sockets, pintar ventanas, etc.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;El porcentaje de consumo en modo usuario corresponde a la ejecución de código sin interacción con el &lt;em&gt;kernel&lt;/em&gt;, es decir, algo así como &amp;quot;el código sin acceso a recursos externos.&amp;quot; Si estuviésemos utilizando un &lt;em&gt;profiler&lt;/em&gt;, diríamos entonces que corresponde a lo que se llama &amp;quot;exclusive time.&amp;quot;&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Contadores&lt;/strong&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;La siguiente es la lista de contadores de perfmon a utilizar, que como podrán notar, es muy breve, repetitiva y casi no requiere mayor explicación.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Objeto System, contador Processor Queue Length: muestra la cantidad de requerimientos encolados para el procesador.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Objeto Processor, contador % Privileged Time: muestra el porcentaje de tiempo utilizado por el kernel, para todo el procesador&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Objeto Processor, contador % User Time: similar al anterior, pero para modo usuario&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Objeto Process, contador % Privileged Time, instancia específica. muestra el porcentaje de tiempo utilizado por el kernel, para la aplicación seleccionada en el campo instancia&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Objeto Process, contador % User Time, instancia específica: similar al anterior, pero para modo usuario&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Objeto Thread, contador % Privileged Time, instancia específica: muestra el porcentaje de tiempo utilizado por el kernel, para un thread especifico de la aplicación seleccionada&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Objeto Thread, contador % User Time, instancia especifica: similar al anterior, pero para modo usuario&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Probablemente te podrás estar preguntando la utilidad de la información de los últimos 2 contadores. ¿de que te serviría saber cuál es el &lt;em&gt;thread&lt;/em&gt; responsable si no se puede hacer mucho con esa información?&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Si se puede hacer bastante. Puedes determinar si es un único &lt;em&gt;thread&lt;/em&gt; que está ocupando mucho el procesador o es un conjunto de ellos en que todos aportan. Te sirve para obtener pistas.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Podría ser el &lt;em&gt;thread&lt;/em&gt; o los &lt;em&gt;threads&lt;/em&gt; del GC, el &lt;em&gt;thread&lt;/em&gt; del Finalizador, un &lt;em&gt;thread&lt;/em&gt; que se quedó pegado en un ciclo, etc. &lt;em&gt;&lt;a href="http://www.microsoft.com/technet/sysinternals/ProcessesAndThreads/ProcessExplorer.mspx"&gt;Process Explorer&lt;/a&gt;&lt;/em&gt; entrega mucha información referente a tipos de procesos e informacón de los &lt;em&gt;threads&lt;/em&gt;.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Ok, ya tengo todos los datos...&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;¿Contra qué comparar la información?&lt;/strong&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Salvo para el primer contador, no hay punto de comparación. Si el uso del procesador llega a 80% o más, probablemente sea hora de proveer alivio al servidor, ya sea corrigiendo el código o haciendo un upgrade del hardware.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;El primer contador no debe ser mayor a 2 multiplicado por la cantidad de procesadores (&lt;em&gt;cores&lt;/em&gt;) de tu servidor. Para el caso de HT (&lt;em&gt;Hyper Threading&lt;/em&gt;), no estoy seguro, pero creo que no se deben contabilizar.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Ya vendrá una tercera entrega relacionada con el disco duro.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Saludos,&lt;br /&gt;Patrick&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1401057" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/pmackay/archive/tags/Tips/default.aspx">Tips</category><category domain="http://msmvps.com/blogs/pmackay/archive/tags/Windows+y+Microsoft/default.aspx">Windows y Microsoft</category></item><item><title>Signos vitales de un servidor: Parte I (memoria)</title><link>http://msmvps.com/blogs/pmackay/archive/2007/12/08/post27.aspx</link><pubDate>Sat, 08 Dec 2007 21:34:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1387401</guid><dc:creator>pmackay</dc:creator><slash:comments>1</slash:comments><comments>http://msmvps.com/blogs/pmackay/archive/2007/12/08/post27.aspx#comments</comments><description>&lt;p&gt;&lt;span style="FONT-SIZE:12pt;COLOR:#ffffff;FONT-FAMILY:Calibri;BACKGROUND-COLOR:#008000;"&gt;¿Qué&lt;/span&gt;&lt;font face="Calibri"&gt;&lt;font style="FONT-SIZE:12pt;"&gt; sucede si uno no se siente bien?; en condiciones normales, uno visita al doctor para saber qué sucede y éste hace una revisión general. Si el doctor encuentra algo interesante, te pide hacer unos exámenes para saber con mayor detalle qué está sucediendo.&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Calibri"&gt;&lt;font style="FONT-SIZE:12pt;"&gt;Llevando este mismo ejemplo al área de la informática, si tienes un servidor y presientes (o tienes total certeza) que algo no funciona como debiera, un buen punto de partida es determinar si los signos vitales de éste están bien.&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;El &lt;font face="Calibri"&gt;&lt;font style="FONT-SIZE:12pt;"&gt;objetivo de este post es dar una pauta general para determinar cuando un servidor Windows 2003, cualquier versión, puede tener algún problema que afecte sus signos vitales. Hoy veremos los signos vitales de la memoria. Los siguientes &lt;em&gt;posts&lt;/em&gt; abordarán otras áreas. &lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font style="FONT-SIZE:12pt;" face="Calibri"&gt;&lt;strong&gt;Un poco de contexto&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font style="FONT-SIZE:12pt;" face="Calibri"&gt;Si has escuchado muchas veces la palabra contadores, y no tienes claro a que se refieren cuando lo escuchas, esta sección debiera aclararte un poco. Si tienes claro a que se refiere, puedes saltarte&amp;nbsp; esta sección.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font style="FONT-SIZE:12pt;" face="Calibri"&gt;Los contadores son entidades u objetos que mantienen información del funcionamiento de algún programa o sistema operativo (SO de ahora en adelante). Cada programa que utilizas --&lt;em&gt;todos debieran, pero no siempre lo hacen&lt;/em&gt;-- genera información con estadística y en tiempo real del funcionamiento de éste, la cual se le informa al SO. A su vez, el SO también genera información que almacena para que nosotros podamos consultarla y saber cómo está funcionando.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font style="FONT-SIZE:12pt;" face="Calibri"&gt;Los contadores se categorizan por objetos (por ejemplo, memoria, sistema, sql server, iis) y se pueden o no aplicar a instancias (procesos, sitios web, bases de datos, etc.)&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font style="FONT-SIZE:12pt;" face="Calibri"&gt;Por ejemplo, un contador de importante SO es la cantidad de memoria disponible que le queda. Este se categoriza en el objeto &lt;em&gt;Memory&lt;/em&gt;, y el contador se llama &lt;em&gt;Available MBytes&lt;/em&gt;, que nos dice la cantidad de megabytes de memoria disponible. Los nombres de los contadores dependen del idioma del programa o SO. Si estás ejecutando un SO en español, el objeto podría llamarse &lt;em&gt;Memoria&lt;/em&gt; y el contador, &lt;em&gt;cantidad de MB disponibles&lt;/em&gt;.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font style="FONT-SIZE:12pt;" face="Calibri"&gt;La siguiente es una imagen de cómo se agrega este contador utilizando &lt;em&gt;performance monitor&lt;/em&gt; (perfmon).&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;img height="216" src="http://msmvps.com/blogs/pmackay/post27/27-01b.Png" width="373" border="1" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;font style="FONT-SIZE:12pt;" face="Calibri"&gt;Luego, después de habar agregado los contadores, podrás ver una pantalla como ésta, donde la primera es la representación gráfica y la otra la textual, para la misma información.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;img height="312" src="http://msmvps.com/blogs/pmackay/post27/27-02b.Png" width="416" border="1" alt="" /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img height="67" src="http://msmvps.com/blogs/pmackay/post27/27-03b.Png" width="399" border="1" alt="" /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;font style="FONT-SIZE:12pt;" face="Calibri"&gt;Suponiendo que ya se entiende la idea, vamos entonces a ver la primera parte de cómo chequear la salud de un sistema operativo.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font style="FONT-SIZE:12pt;" face="Calibri"&gt;&lt;strong&gt;Grupos de contadores &lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font style="FONT-SIZE:12pt;" face="Calibri"&gt;Aunque los contadores ya están agrupados de acuerdo a los objetos a los cuales pertenecen, los volveremos a agrupar en clasificaciones más grandes, más generales. Tendremos entonces un grupo para colocar los contadores de memoria, uno para los del procesador, otro para el disco duro, otro para la tarjeta de red y otro para el sistema operativo. En otra oportunidad veremos los asociados a productos específicos como SQL, IIS o .NET.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font style="FONT-SIZE:12pt;" face="Calibri"&gt;&lt;strong&gt;Contadores de memoria&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font style="FONT-SIZE:12pt;" face="Calibri"&gt;Los contadores de memoria son variados. Podemos encontrar desde la memoria utilizada por una aplicación, la memoria libre del servidor y la memoria utilizada por los componentes del &lt;em&gt;Kernel&lt;/em&gt; del SO. Todas estas son importantes y están de alguna forma relacionadas.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font style="FONT-SIZE:12pt;" face="Calibri"&gt;Veamos cada uno de los contadores mencionados y contra qué compararlos (cuando aplica).&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font style="FONT-SIZE:12pt;" face="Calibri"&gt;&lt;strong&gt;Memoria del sistema (incluido kernel)&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font style="FONT-SIZE:12pt;" face="Calibri"&gt;La memoria libre del sistema la entrega el contador &lt;em&gt;Available MBytes&lt;/em&gt;, del objeto &lt;em&gt;Memory&lt;/em&gt;. El mismo contador existe retornando el valor en otras unidades como &lt;em&gt;KBytes&lt;/em&gt; y &lt;em&gt;Bytes&lt;/em&gt;. De acuerdo a la cantidad de memoria que hoy en día tiene un servidor, medir en bytes o kilobytes puede no ser necesario.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font style="FONT-SIZE:12pt;" face="Calibri"&gt;Diversa documentación podrán encontrar referente a este contador. Algunos dirán que con 10 MB disponibles, es momento de preocuparse. Otros dirán que 25 MB es una señal de preocupación. En general, menos del 10% de la memoria total instalada ya es reflejo de que al sistema le falta memoria. Por ejemplo, si mi servidor tiene 2GB instalados y le quedan 150 MB disponibles, significa que estoy consumiendo el 92,5% de la memoria. Sin embargo, otros contadores te ayudarán a determinar si esto es cierto o no (si hay o no un problema). Puede ser que tengas mucha memoria ocupada, pero el sistema funcione bien.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font style="FONT-SIZE:12pt;" face="Calibri"&gt;Otro contador importante es &lt;em&gt;Pages/sec&lt;/em&gt; del objeto &lt;em&gt;Memory&lt;/em&gt;. Este refleja la tasa de lecturas y escrituras a disco para resolver problemas de páginas no encontradas (&lt;em&gt;hard faults&lt;/em&gt;) en la memoria física, y por ende, tiene que ir al archivo de paginación a buscarla (y guardar otra para hacer espacio).&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;La información disponible públicamente es muy variada. &lt;/span&gt;&lt;font style="FONT-SIZE:12pt;" face="Calibri"&gt;Desde sitios que dicen que valores de más de 100 son preocupantes. Otros dicen que más de 5 de forma constante es preocupante. Lamentablemente ninguna de esas medidas es agnóstica y depende de otros factores (como el disco). Una medida agnóstica se obtiene al multiplicar este contador por &lt;em&gt;Avg. Disk sec/Transfer&lt;/em&gt; del objeto &lt;em&gt;Physical Disk&lt;/em&gt;, en la instancia (disco) donde está el archivo de paginación. El resultado de multiplicar ambos corresponde al porcentaje de tiempo de acceso a disco. Si es mayor a 10%, está paginando mucho, lo que puede ser producto de falta de memoria.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font style="FONT-SIZE:12pt;" face="Calibri"&gt;Los contadores de memoria del kernel se deben comparar contra valores en unas tablas específicas. Estos son &lt;em&gt;Pool Paged Bytes&lt;/em&gt; y &lt;em&gt;Pool Nonpaged Bytes&lt;/em&gt; del objeto &lt;em&gt;Memory&lt;/em&gt;. Las tablas se encuentran a continuación, tanto para Windows 2000 como Windows 2003 (clic para agrandar).&lt;/font&gt;&lt;/p&gt;
&lt;table class="" cellpadding="2"&gt;

&lt;tr&gt;
&lt;td class=""&gt;&lt;a href="http://msmvps.com/blogs/pmackay/post27/27-04b.png" target="_blank"&gt;&lt;img style="BORDER-TOP-WIDTH:0px;BORDER-LEFT-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-RIGHT-WIDTH:0px;" height="185" src="http://msmvps.com/blogs/pmackay/post27/27-04s.png" width="154" alt="" /&gt;&lt;/a&gt; &lt;br /&gt;&lt;font style="FONT-SIZE:12pt;" face="Calibri"&gt;Windows 2003&lt;/font&gt;&lt;/td&gt;
&lt;td class=""&gt;&lt;a href="http://msmvps.com/blogs/pmackay/post27/27-05b.png" target="_blank"&gt;&lt;img style="BORDER-TOP-WIDTH:0px;BORDER-LEFT-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-RIGHT-WIDTH:0px;" height="137" src="http://msmvps.com/blogs/pmackay/post27/27-05s.png" width="160" alt="" /&gt;&lt;/a&gt; &lt;br /&gt;&lt;font style="FONT-SIZE:12pt;" face="Calibri"&gt;Windows 2000 SP4&lt;/font&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;&lt;font style="FONT-SIZE:12pt;" face="Calibri"&gt;Los valores obtenidos para cada unos de los contadores, tanto para &lt;em&gt;paged&lt;/em&gt; como &lt;em&gt;nonpaged&lt;/em&gt;, corresponden a la cantidad de bytes de cada pool que ha sido utilizado. Si es menor al 50% del pool, todo está bien. Mayor a 50% y menor a 80%, es hora de preocuparse. Si es mayor a 80%, hay problemas.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;¿Cómo se mide?&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Si obtuviste un valor de 56 MB en el contador de &lt;em&gt;paged pool bytes&lt;/em&gt; y tu sistema es Windows 2003 con 4 GB y estás usando /3GB, el tamaño total del &lt;em&gt;paged pool bytes&lt;/em&gt; es de 258 MB (revisa la tabla). La tasa de uso (56/258) es cercana al 21%, lo que nos dice que nuestro sistema está bien. Lo mismo para &lt;em&gt;nonpaged pool bytes&lt;/em&gt;, pero considerando el otro valor en la tabla.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;El último contador relacionado con la memoria en el kernel corresponde a &lt;em&gt;Free System Page Table Entries (PTEs)&lt;/em&gt;, del objeto &lt;em&gt;Memory&lt;/em&gt;. Los PTEs son estructuras internas utilizadas por el componente del kernel llamado &lt;em&gt;Memory Manager&lt;/em&gt; y que tiene como objetivo administrar la memoria. &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Si este contador se reduce mucho (menos de 15 mil o 10 mil), habrá problemas. Usualmente este contador se ve afectado por la utilización de la opción &lt;em&gt;/3GB&lt;/em&gt; sin utilizar la opción &lt;em&gt;/userva&lt;/em&gt;. &lt;a href="http://msmvps.com/blogs/pmackay/archive/2007/06/24/post12.aspx" target="_blank"&gt;Esta anécdota&lt;/a&gt; ocurrió en un caso donde no se utilizó &lt;em&gt;/userva&lt;/em&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Después de haber visto las opciones para el sistema y kernel, podemos ver las opciones de memoria disponibles para las aplicaciones.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;font style="FONT-SIZE:12pt;" face="Calibri"&gt;&lt;strong&gt;Memoria de aplicaciones&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font style="FONT-SIZE:12pt;" face="Calibri"&gt;Para medir la memoria de una aplicación específica, tengo que agregar los siguientes contadores, y asociarlos con el proceso que quiero medir (instancia en la parte derecha de la ventana):&lt;/font&gt;&lt;/p&gt;&lt;font style="FONT-SIZE:12pt;" face="Calibri"&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Objeto &lt;em&gt;Process&lt;/em&gt;, contador &lt;em&gt;Private Bytes&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Objeto &lt;em&gt;Process&lt;/em&gt;, contador &lt;em&gt;Virtual Bytes&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Objeto &lt;em&gt;Process&lt;/em&gt;, contador &lt;em&gt;Working Set&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/font&gt;
&lt;p&gt;&lt;font style="FONT-SIZE:12pt;" face="Calibri"&gt;El primer contador corresponde a la memoria privada el proceso. El segundo contador, a la memoria virtual del proceso. Para un mejor entendimiento de los tipos de memoria que miden, te recomiendo la lectura de estos posts:&lt;/font&gt;&lt;/p&gt;&lt;font style="FONT-SIZE:12pt;" face="Calibri"&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/blogs/pmackay/archive/2007/02/02/netadmin.aspx"&gt;http://msmvps.com/blogs/pmackay/archive/2007/02/02/netadmin.aspx&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/blogs/pmackay/archive/2007/06/24/post12.aspx"&gt;http://msmvps.com/blogs/pmackay/archive/2007/06/24/post12.aspx&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/font&gt;
&lt;p&gt;&lt;font style="FONT-SIZE:12pt;" face="Calibri"&gt;El &lt;em&gt;working set&lt;/em&gt; corresponde a la cantidad de memoria&amp;nbsp;privada (sumada a la memoria usada por dlls y otras estructuras) que está cargada en memoria real (física). A grosso modo, la suma de los &lt;em&gt;working set&lt;/em&gt; de todos los procesos no podrá superar la memora física de tu máquina.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font style="FONT-SIZE:12pt;" face="Calibri"&gt;Lamentablemente no hay valores contra qué compararlos, pero de acuerdo a lo que vimos en el segundo post de la lista de más arriba, la memoria virtual no podrá superar los 2 GB&amp;nbsp;en un sistema de 32 bits. &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font style="FONT-SIZE:12pt;" face="Calibri"&gt;Si &lt;em&gt;virtual bytes&lt;/em&gt; es &lt;strong&gt;muy elevado&lt;/strong&gt; en comparación con &lt;em&gt;private bytes&lt;/em&gt;, podría haber un problema de fragmentación de memoria. ¿Qué significa muy elevado?; tampoco hay una respuesta, pero unas 10 veces debiera ser preocupante, como también es preocupante acercarse a los 2 GB. Claro que las 10 veces dependerá de la memoria que use nuestro proceso. Si un proceso utiliza 10 MB de memoria privada, es normal que utilice 100 MB de memoria virtual.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font style="FONT-SIZE:12pt;" face="Calibri"&gt;Hay muchas cosas relativas, pero lo importante es monitorearlos en el tiempo.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Si &lt;em&gt;virtual bytes&lt;/em&gt; sube y sube sin descender (o descendiendo menos de lo que aumenta), habrá un problema de fragmentación de memoria, aunque dependerá de cómo aumente &lt;em&gt;private bytes&lt;/em&gt; también.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Si &lt;em&gt;private bytes&lt;/em&gt; sube y sube sin descender (o descendiendo menos de lo que aumenta), tendrás un problema de pérdida de memoria o &lt;em&gt;memory leak&lt;/em&gt;. &lt;em&gt;Private bytes&lt;/em&gt; no podrá ser superior al máximo de memoria virtual de un proceso (2GB).&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Otros contadores&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Sin duda, hay muchos más contadores, pero para determinar signos vitales, con éstos basta.&lt;/span&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Desde Santiago de Chile,&lt;br /&gt;Patrick&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1387401" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/pmackay/archive/tags/Tips/default.aspx">Tips</category><category domain="http://msmvps.com/blogs/pmackay/archive/tags/Memoria+y+GC/default.aspx">Memoria y GC</category></item><item><title>Desmitificando la Encriptación (ex MTJ.NET)</title><link>http://msmvps.com/blogs/pmackay/archive/2007/11/30/post28.aspx</link><pubDate>Fri, 30 Nov 2007 04:00:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1436186</guid><dc:creator>pmackay</dc:creator><slash:comments>0</slash:comments><comments>http://msmvps.com/blogs/pmackay/archive/2007/11/30/post28.aspx#comments</comments><description>&lt;h4 style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Aclaración&lt;/h4&gt;
&lt;p style="FONT-SIZE:12pt;COLOR:#cc3300;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;El siguiente contenido apareció publicado en la revista MTJ.NET en MSDN en español en el año 2005, en partes I y II. Debido a que la revista MTJ.NET no está al aire hoy, he optado por lanzarlo al aire nuevamente desde mi blog en un sólo documento. &lt;/strong&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;COLOR:#cc3300;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;&lt;em&gt;A los suscriptores RSS les pido disculpas de antemano por haber publicado diferentes versiones.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-FAMILY:Calibri;"&gt;&lt;font size="3"&gt;Código fuente disponible &lt;/font&gt;&lt;a href="http://msmvps.com/blogs/pmackay/otros/Desmitificando%20la%20Encriptación%20(Parte%20I).zip" target="_blank"&gt;&lt;font size="3"&gt;aquí&lt;/font&gt;&lt;/a&gt;&lt;font size="3"&gt;.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h4&gt;&lt;span style="FONT-FAMILY:Calibri;"&gt;&lt;font size="3"&gt;Introducción&lt;/font&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span style="FONT-FAMILY:Calibri;"&gt;&lt;font size="3"&gt;Cuando es necesario darle seguridad a ciertos datos de nuestra aplicación, y buscamos información en el &lt;/font&gt;&lt;i&gt;&lt;font size="3"&gt;Web&lt;/font&gt;&lt;/i&gt;&lt;font size="3"&gt; que nos permita lograrlo, es normal que hablemos (o leamos) de encriptación, y que irremediablemente salgan a la luz palabras tales como algoritmos simétricos, asimétricos y &lt;/font&gt;&lt;i&gt;&lt;font size="3"&gt;Hash&lt;/font&gt;&lt;/i&gt;&lt;font size="3"&gt;. Estos términos pueden generar temor o dar la sensación de ser complejos. La motivación de este documento es mostrar qué es la encriptación sin necesidad de profundizar en cómo funciona un algoritmo internamente; y también indicar las malas prácticas que se realizan popularmente. Se revisará además la forma correcta de utilizar los algoritmos de encriptación, dónde se deben usar y dónde no.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Debido a lo extenso del tema en cuestión y a que es preferible realizar todas las explicaciones correspondientes, fue necesario dividir el documento en dos partes. Lo que contendrá cada parte está detallado en el siguiente índice.&lt;/p&gt;
&lt;h4&gt;&lt;span style="FONT-FAMILY:Calibri;"&gt;&lt;font size="3"&gt;Agradecimientos&lt;/font&gt;&lt;/span&gt;&lt;/h4&gt;&lt;span style="FONT-FAMILY:Calibri;"&gt;&lt;font size="3"&gt;Antes de comenzar deseo agradecer tanto el apoyo de Mike Giagnocavo como el de la información disponible en su &lt;/font&gt;&lt;i&gt;&lt;font size="3"&gt;blog&lt;/font&gt;&lt;/i&gt;&lt;font size="3"&gt; (&lt;/font&gt;&lt;a href="http://www.atrevido.net/"&gt;&lt;font size="3"&gt;http://www.atrevido.net/&lt;/font&gt;&lt;/a&gt;&lt;font size="3"&gt;). Sin sus consejos y correcciones, los ejemplos de este documento y la demostración no habrían quedado de excelente calidad y listos para utilizar. &lt;/font&gt;&lt;/span&gt;
&lt;h4&gt;&lt;span style="FONT-FAMILY:Calibri;"&gt;&lt;font size="3"&gt;Introducción, alcance y preguntas iniciales&lt;/font&gt;&lt;/span&gt;&lt;/h4&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;La seguridad de los datos de cualquier sistema es algo muy importante, y no siempre recibe la atención y dedicación necesarias. Podemos formular las siguientes preguntas básicas y es probable que encontremos falencias de seguridad que pueden comprometer a nuestro sistema: &lt;/span&gt;
&lt;ul&gt;
&lt;li style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;¿Se está almacenando la información crítica de forma segura? &lt;/li&gt;
&lt;li style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;¿Qué entendemos por seguro? &lt;/li&gt;
&lt;li style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Si se está encriptando, ¿Qué algoritmo se está utilizando? &lt;/li&gt;
&lt;li style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;¿Se permite la desencriptación de datos que no debieran poder desencriptarse? &lt;/li&gt;
&lt;li style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;¿Cómo está realizándose la encriptación? &lt;/li&gt;&lt;/ul&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Adicionalmente, podemos complementar con preguntas más complejas:&lt;/p&gt;
&lt;ul&gt;
&lt;li style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;¿Dónde están almacenadas la o las llaves? &lt;/li&gt;
&lt;li style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;¿Con qué frecuencia se cambian las llaves? &lt;/li&gt;
&lt;li style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;¿Cómo se enfrenta el problema de cambiar las llaves con tanta frecuencia? &lt;/li&gt;
&lt;li style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;¿Con qué criterio se definen las nuevas llaves? &lt;/li&gt;&lt;/ul&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Es probable que algunas de las preguntas básicas no sean respondidas adecuadamente. Si esto es así, sería recomendable hacer una revisión de los criterios y metodologías que se están utilizando, y determinar si es necesario hacer modificaciones o rehacer esas funcionalidades. Si el pensamiento es que esto no genera utilidad, cabe hacerse las siguientes preguntas: ¿Qué le sucedería al negocio si alguien accediese a cualquiera de los datos privados del sistema? ¿Se verá comprometida la seguridad con hechos como éste? De seguro, en ese momento el pensamiento sería que valdría la pena. Entonces, manos a la obra.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;El alcance de este documento es dar a conocer los distintos métodos que existen para proteger tanto el almacenamiento como el envío de la información. Este documento NO tiene como intención ser un manual de seguridad. Esto es lo mínimo que debe tener una organización para no estar al descubierto en sus procesos. Se debe entender que existen libros dedicados a la seguridad. Aquí se está danto el puntapié inicial para salir del desconocimiento que existe sobre este tema. Es responsabilidad tanto de los administradores&amp;nbsp; de sistemas operativos como del arquitecto de soluciones definir las reglas, dónde almacenar sus llaves, los criterios de cambio de llaves y también los lugares donde almacenará la información.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Habiendo introducido el tema y definido el alcance, comencemos con la revisión de los algoritmos y los distintos tipos que existen. &lt;/p&gt;
&lt;h4&gt;&lt;span style="FONT-FAMILY:Calibri;"&gt;&lt;font size="3"&gt;Definición de algoritmos&lt;/font&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Como se mencionó con anterioridad, existen distintos tipos de algoritmos de encriptación, pero algo que no se ha mencionado hasta ahora son los “algoritmos” que se cree que encriptan, pero que no hacen nada más que transformar texto (o información). El objetivo de hacer esta distinción es mostrar algunas malas prácticas que se cometen, pensando que cualquier algoritmo que cambia de cierta forma un texto, está realizando encriptación de datos. Estos algoritmos podremos llamarlos simplemente &amp;quot;Transformaciones&amp;quot;.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Como se está hablando de encriptación, se revisarán también los algoritmos que han sido construidos con distintos fines y que están agrupados en distintas categorías. ¿Cuál es la funcionalidad de los algoritmos dentro de cada uno de estos grupos? Cada uno tiene un objetivo y un problema que atacar, y por lo mismo hay casos en los que debe utilizarse uno y sólo uno de estos algoritmos, como también casos en los que debe utilizarse algoritmos de más de un grupo.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Antes de revisar los escenarios, se debe aclarar el concepto de llave. La llave de encriptación es una serie de carácteres, de determinado largo, que se utiliza para encriptar y desencriptar la información que se quiere proteger. El largo de la llave depende del algoritmo. Existen llaves privadas y públicas, que serán detalladas más adelante. Veamos los siguientes escenarios.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;&lt;font size="3"&gt;Escenario 1&lt;/font&gt;&lt;/strong&gt;&lt;font size="3"&gt;: Necesito almacenar información crítica que deberá poder descifrarse, y seré yo el único que haga todo el proceso. Nadie más tendrá acceso a la llave con que se encriptará y desencriptará la información. &lt;/font&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;&lt;font size="3"&gt;Escenario 2&lt;/font&gt;&lt;/strong&gt;&lt;font size="3"&gt;: Necesito que me envíen información crítica que yo desencriptaré posteriormente, pero necesito que las personas que me van a enviar información pueden encriptarla libremente, pero no desencriptarla. En este caso, se deja disponible una llave pública para que ellos encripten y yo tendré mi llave privada de encriptación en forma segura. &lt;/font&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;&lt;font size="3"&gt;Escenario 3&lt;/font&gt;&lt;/strong&gt;&lt;font size="3"&gt;: Necesito almacenar o enviar información crítica de forma segura, pero que no requerirá ser desencriptada para su validación, o que es extremadamente importante verificar que no haya sido modificada en el camino. &lt;/font&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Estos son los tres escenarios más comunes. Es probable que te preguntes para qué puede haber casos como el 3. Lo veremos más adelante con ejemplos, destacando ventajas y desventajas. Los tres escenarios calzan con los algoritmos listados a continuación:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;&lt;font size="3"&gt;Escenario 1&lt;/font&gt;&lt;/strong&gt;&lt;font size="3"&gt;: Encriptación simétrica &lt;/font&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;&lt;font size="3"&gt;Escenario 2&lt;/font&gt;&lt;/strong&gt;&lt;font size="3"&gt;: Encriptación asimétrica &lt;/font&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;&lt;font size="3"&gt;Escenario 3&lt;/font&gt;&lt;/strong&gt;&lt;font size="3"&gt;: &lt;/font&gt;&lt;i&gt;&lt;font size="3"&gt;Hash&lt;/font&gt;&lt;/i&gt;&lt;font size="3"&gt; de información &lt;/font&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Antes de comenzar a revisar cada uno de estos algoritmos, revisemos una muy mala práctica que se utiliza más de lo que debiera, que corresponde a la utilización de “algoritmos” o mejor dicho, transformaciones del contenido.&lt;/p&gt;
&lt;h4&gt;&lt;span style="FONT-FAMILY:Calibri;"&gt;&lt;font size="3"&gt;Malas prácticas o transformaciones&lt;/font&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span style="FONT-FAMILY:Calibri;"&gt;&lt;font size="3"&gt;Antes mencionamos que es común escuchar o ver que se utilizan ciertas transformaciones como métodos de protección. Como la comparación se hace con el ojo humano, si se tiene una cadena de texto y se decide transformar aplicándole un XOR o desplazando los &lt;/font&gt;&lt;i&gt;&lt;font size="3"&gt;bytes&lt;/font&gt;&lt;/i&gt;&lt;font size="3"&gt;, el resultado de esa transformación nos produce el efecto de que está encriptado, por que no lo podemos entender (nuestro cerebro no lo entiende). Debido a esto, no vamos a hacer el ejemplo transformando texto sino que lo haremos transformando una imagen. Se aplicarán los dos efectos mencionados recién, XOR y Desplazamiento, y se verá que es efectivamente lo que hacen. El motivo de utilizar una imagen es para que nuestro ojo no se engañe con las apariencias.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-FAMILY:Calibri;"&gt;&lt;font size="3"&gt;Nuestro ejemplo nos presenta una pantalla como la que se muestra en la Figura 1, donde tenemos dos botones; uno para cargar la imagen, otro para aplicarle las transformaciones XOR, y otro para desplazar los &lt;/font&gt;&lt;i&gt;&lt;font size="3"&gt;bytes&lt;/font&gt;&lt;/i&gt;&lt;font size="3"&gt;:&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p align="center"&gt;&lt;span style="FONT-FAMILY:Calibri;"&gt;&lt;font size="3"&gt;&lt;br /&gt;&lt;img height="392" src="http://msmvps.com/blogs/pmackay/mtjnet/mtjnet-art216-img01-482x392.jpg" width="482" alt="" /&gt;&lt;br /&gt;&lt;/font&gt;&lt;b&gt;&lt;font size="3"&gt;Figura 1&lt;/font&gt;&lt;/b&gt;&lt;font size="3"&gt;.&lt;/font&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-FAMILY:Calibri;"&gt;&lt;font size="3"&gt;Si se presiona Transformar, el resultado será el que se muestra en la figura 2: &lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p align="center"&gt;&lt;span style="FONT-FAMILY:Calibri;"&gt;&lt;font size="3"&gt;&lt;br /&gt;&lt;img height="392" src="http://msmvps.com/blogs/pmackay/mtjnet/mtjnet-art216-img02-482-392.jpg" width="482" alt="" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/font&gt;&lt;b&gt;&lt;font size="3"&gt;Figura 2&lt;/font&gt;&lt;/b&gt;&lt;font size="3"&gt;: Resultado de las transformaciones.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-FAMILY:Calibri;"&gt;&lt;font size="3"&gt;Como se puede apreciar, no se produce una encriptación sino sólo una transformación de los datos (más adelante verás cómo queda la imagen realmente encriptada). Este tipo de transformaciones no protege nuestra información. Hagamos ahora las siguientes preguntas: ¿Cuánta seguridad existe con estas transformaciones? ¿Cuánto demorará un &lt;/font&gt;&lt;i&gt;&lt;font size="3"&gt;hacker&lt;/font&gt;&lt;/i&gt;&lt;font size="3"&gt; en retransformar esto? El &lt;/font&gt;&lt;i&gt;&lt;font size="3"&gt;hacker &lt;/font&gt;&lt;/i&gt;&lt;font size="3"&gt;obtiene la respuesta en menos de lo que te toma a ti leer sólo esta línea. Hacerle modificaciones a este “algoritmo” no sirve. La encriptación no es trivial de hacer, pero es mucho más fácil de usar. Más adelante conocerás&amp;nbsp; la cantidad de años que estuvo estudiándose el algoritmo &lt;/font&gt;&lt;i&gt;&lt;font size="3"&gt;Rijndael&lt;/font&gt;&lt;/i&gt;&lt;font size="3"&gt; o AES, para ser declarado vencedor. &lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-FAMILY:Calibri;"&gt;&lt;font size="3"&gt;El código que utilizamos para realizar la transformación XOR es el siguiente. El código de desplazamiento es muy similar. Este, al igual que todo el código del documento, está disponible en el archivo adjunto con este artículo. Por motivos que no corresponde explicar aquí, ya que no entran en el objetivo del documento, con la imagen que se está trabajando es necesario comenzar desde la posición 34, ya que si se comienza desde el &lt;/font&gt;&lt;i&gt;&lt;font size="3"&gt;byte&lt;/font&gt;&lt;/i&gt;&lt;font size="3"&gt; 0 transformando, el archivo BMP ya no es posible visualizarlo. &lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-FAMILY:Calibri;"&gt;&lt;font size="3"&gt;Lo único que hace este “algoritmo” es aplicar XOR a un arreglo de &lt;/font&gt;&lt;i&gt;&lt;font size="3"&gt;bytes&lt;/font&gt;&lt;/i&gt;&lt;font size="3"&gt;. Para aplicarlo sobre texto lo único que hay que hacer son las transformaciones de &lt;/font&gt;&lt;i&gt;&lt;font size="3"&gt;bytes&lt;/font&gt;&lt;/i&gt;&lt;font size="3"&gt; a texto y viceversa. Como explicación sencilla de este proceso, podemos decir que lo que hace es tomar cada uno de los &lt;/font&gt;&lt;i&gt;&lt;font size="3"&gt;bytes&lt;/font&gt;&lt;/i&gt;&lt;font size="3"&gt; y aplicarle un XOR (representado por el símbolo &amp;quot;^&amp;quot; en el código). Un XOR corresponde al resultado de la comparación &lt;/font&gt;&lt;i&gt;&lt;font size="3"&gt;bit&lt;/font&gt;&lt;/i&gt;&lt;font size="3"&gt; a &lt;/font&gt;&lt;i&gt;&lt;font size="3"&gt;bit&lt;/font&gt;&lt;/i&gt;&lt;font size="3"&gt; de dos &lt;/font&gt;&lt;i&gt;&lt;font size="3"&gt;bytes&lt;/font&gt;&lt;/i&gt;&lt;font size="3"&gt;. En este caso, un &lt;/font&gt;&lt;i&gt;&lt;font size="3"&gt;byte&lt;/font&gt;&lt;/i&gt;&lt;font size="3"&gt; viene del texto a transformar y el otro del número 87 elegido al azar.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table class="" cellspacing="0" cellpadding="0" bgcolor="lightgrey"&gt;

&lt;tr&gt;
&lt;td class=""&gt;
&lt;p&gt;&lt;span style="FONT-FAMILY:Calibri;"&gt;&lt;span style="FONT-SIZE:12pt;COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE:12pt;COLOR:blue;"&gt;class&lt;/span&gt;&lt;font size="3"&gt; TransformacionXOR&lt;br /&gt;&lt;/font&gt;{&lt;font size="3"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;span style="FONT-SIZE:12pt;COLOR:blue;"&gt;private&lt;/span&gt; &lt;span style="FONT-SIZE:12pt;COLOR:blue;"&gt;static&lt;/span&gt; &lt;span style="FONT-SIZE:12pt;COLOR:blue;"&gt;int&lt;/span&gt;&lt;font size="3"&gt; _XOR = 87;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;span style="FONT-SIZE:12pt;COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE:12pt;COLOR:blue;"&gt;static&lt;/span&gt; &lt;span style="FONT-SIZE:12pt;COLOR:blue;"&gt;byte&lt;/span&gt;&lt;font size="3"&gt;[] Codificar(&lt;/font&gt;&lt;span style="FONT-SIZE:12pt;COLOR:blue;"&gt;byte&lt;/span&gt;&lt;font size="3"&gt;[] bytACodificar)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;span style="FONT-SIZE:12pt;COLOR:blue;"&gt;for&lt;/span&gt;&lt;font size="3"&gt; (&lt;/font&gt;&lt;span style="FONT-SIZE:12pt;COLOR:blue;"&gt;int&lt;/span&gt;&lt;font size="3"&gt; _intPos = &lt;/font&gt;&lt;b&gt;&lt;font size="3"&gt;34&lt;/font&gt;&lt;/b&gt;&lt;font size="3"&gt;; _intPos &amp;lt; bytACodificar.Length; _intPos++)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;span&gt;&lt;font size="3"&gt;bytACodificar[_intPos] = (&lt;/font&gt;&lt;span style="FONT-SIZE:12pt;COLOR:blue;"&gt;byte&lt;/span&gt;&lt;font size="3"&gt;) (_XOR ^ bytACodificar[_intPos]);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:12pt;COLOR:blue;"&gt;return&lt;/span&gt;&lt;font size="3"&gt; bytACodificar; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;span style="FONT-SIZE:12pt;COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE:12pt;COLOR:blue;"&gt;static&lt;/span&gt; &lt;span style="FONT-SIZE:12pt;COLOR:blue;"&gt;byte&lt;/span&gt;&lt;font size="3"&gt;[] DeCodificar(&lt;/font&gt;&lt;span style="FONT-SIZE:12pt;COLOR:blue;"&gt;byte&lt;/span&gt;&lt;font size="3"&gt;[] bytADecodificar)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;span style="FONT-SIZE:12pt;COLOR:blue;"&gt;for&lt;/span&gt;&lt;font size="3"&gt; (&lt;/font&gt;&lt;span style="FONT-SIZE:12pt;COLOR:blue;"&gt;int&lt;/span&gt;&lt;font size="3"&gt; _intPos = &lt;/font&gt;&lt;b&gt;&lt;font size="3"&gt;34&lt;/font&gt;&lt;/b&gt;&lt;font size="3"&gt;; _intPos &amp;lt; bytADecodificar.Length; _intPos++)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;span&gt;&lt;font size="3"&gt;bytADecodificar[_intPos] = (&lt;/font&gt;&lt;span style="FONT-SIZE:12pt;COLOR:blue;"&gt;byte&lt;/span&gt;&lt;font size="3"&gt;) (_XOR ^ bytADecodificar[_intPos]); &lt;/font&gt;&lt;/span&gt;&lt;font size="3"&gt;&lt;br /&gt;&lt;/font&gt;&lt;span&gt;&lt;font size="3"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;span style="FONT-SIZE:12pt;COLOR:blue;"&gt;return&lt;/span&gt;&lt;font size="3"&gt; bytADecodificar;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/span&gt;&lt;font size="3"&gt;&lt;br /&gt;&lt;/font&gt;&lt;span style="FONT-SIZE:12pt;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Como ven, este algoritmo tan lineal no nos da ninguna seguridad; y por lo mismo, jamás debe utilizarse para proteger información. No debe creerse que es XOR el responsable de esto. XOR es muy útil en otros contextos, pero no se puede utilizar de esta forma. &lt;/p&gt;
&lt;blockquote&gt;
&lt;p class="txt-msdn-notas" style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;em&gt;Nota: Antes de continuar, es muy importante aclarar lo siguiente. Si se va a proteger información, el proceso DEBE realizarse a conciencia y con algoritmos probados. Además, se debe utilizar el algoritmo de la forma en que fue concebido. Implementaciones a medias, son tan inútiles como las transformaciones recién vistas o como la no utilización de ésta. O el proceso se hace bien, o no se hace. &lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Veamos ahora los algoritmos reales de encriptación. &lt;/p&gt;
&lt;h4&gt;&lt;span style="FONT-FAMILY:Calibri;"&gt;&lt;font size="3"&gt;Encriptación simétrica&lt;/font&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Cuando hablamos de encriptación y no de transformación, ya estamos adentrándonos en temas de mayor protección, de algoritmos conocidos y seguridad real. El proceso de realizar una encriptación es complejo para ser entendido por nosotros mismos, pero no es limitante para conocer cuáles son los pasos para utilizarlos y qué errores no se deben cometer.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Dentro de los algoritmos de encriptación simétrica podemos encontrar los siguientes, algunos más seguros que otros.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span style="FONT-FAMILY:Calibri;"&gt;&lt;font size="3"&gt;DES (&lt;/font&gt;&lt;i&gt;&lt;font size="3"&gt;Digital Encryption Standard&lt;/font&gt;&lt;/i&gt;&lt;/span&gt;)&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-FAMILY:Calibri;"&gt;&lt;font size="3"&gt;Creado en 1975 con ayuda de la NSA (&lt;/font&gt;&lt;i&gt;&lt;font size="3"&gt;National Security Agency&lt;/font&gt;&lt;/i&gt;&lt;font size="3"&gt;); en 1982 se convirtió en un estándar. Utiliza una llave de 56 &lt;/font&gt;&lt;i&gt;&lt;font size="3"&gt;bit&lt;/font&gt;&lt;/i&gt;&lt;font size="3"&gt;. En 1999 logró ser quebrado (violado) en menos de 24 horas por un servidor dedicado a eso. Esto lo calificó como un algoritmo inseguro y con falencias reconocidas.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span style="FONT-FAMILY:Calibri;"&gt;&lt;font size="3"&gt;3DES (&lt;/font&gt;&lt;i&gt;&lt;font size="3"&gt;Three DES&lt;/font&gt;&lt;/i&gt;&lt;font size="3"&gt; o &lt;/font&gt;&lt;i&gt;&lt;font size="3"&gt;Triple DES&lt;/font&gt;&lt;/i&gt;&lt;font size="3"&gt;)&lt;/font&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-FAMILY:Calibri;"&gt;&lt;font size="3"&gt;&lt;br /&gt;Antes de ser quebrado el DES, ya se trabajaba en un nuevo algoritmo basado en el anterior. Este funciona aplicando tres veces el proceso con tres llaves diferentes de 56 &lt;/font&gt;&lt;i&gt;&lt;font size="3"&gt;bits&lt;/font&gt;&lt;/i&gt;&lt;font size="3"&gt;. La importancia de esto es que si alguien puede descifrar una llave, es casi imposible poder descifrar las tres y utilizarlas en el orden adecuado. Hoy en día es uno de los algoritmos simétricos más seguros.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span style="FONT-FAMILY:Calibri;"&gt;&lt;font size="3"&gt;IDEA (&lt;/font&gt;&lt;i&gt;&lt;font size="3"&gt;International Data Encryption Algorithm&lt;/font&gt;&lt;/i&gt;&lt;font size="3"&gt;)&lt;/font&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-FAMILY:Calibri;"&gt;&lt;font size="3"&gt;&lt;br /&gt;Más conocido como un componente de PGP (encriptación de &lt;/font&gt;&lt;i&gt;&lt;font size="3"&gt;mails&lt;/font&gt;&lt;/i&gt;&lt;font size="3"&gt;), trabaja con llaves de 128 &lt;/font&gt;&lt;i&gt;&lt;font size="3"&gt;bits&lt;/font&gt;&lt;/i&gt;&lt;font size="3"&gt;. Realiza procesos de &lt;/font&gt;&lt;i&gt;&lt;font size="3"&gt;shift&lt;/font&gt;&lt;/i&gt;&lt;font size="3"&gt; y copiado y pegado de los 128 &lt;/font&gt;&lt;i&gt;&lt;font size="3"&gt;bits&lt;/font&gt;&lt;/i&gt;&lt;font size="3"&gt;, dejando un total de 52 sub llaves de 16 &lt;/font&gt;&lt;i&gt;&lt;font size="3"&gt;bits&lt;/font&gt;&lt;/i&gt;&lt;font size="3"&gt; cada una. Es un algoritmo más rápido que el DES, pero al ser nuevo, aún no es aceptado como un estándar, aunque no se le han encontrado debilidades aún. &lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span style="FONT-FAMILY:Calibri;"&gt;&lt;font size="3"&gt;AES (&lt;/font&gt;&lt;i&gt;&lt;font size="3"&gt;Advanced Encryption Standard&lt;/font&gt;&lt;/i&gt;&lt;font size="3"&gt;)&lt;/font&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-FAMILY:Calibri;"&gt;&lt;font size="3"&gt;&lt;br /&gt;Este fue el ganador del primer concurso de algoritmos de encriptación realizado por la NIST (&lt;/font&gt;&lt;i&gt;&lt;font size="3"&gt;National Institute of Standards and Technology&lt;/font&gt;&lt;/i&gt;&lt;font size="3"&gt;) en 1997. Después de 3 años de estudio y habiendo descartado a 14 candidatos, este algoritmo, también conocido como &lt;/font&gt;&lt;i&gt;&lt;font size="3"&gt;Rijndael&lt;/font&gt;&lt;/i&gt;&lt;font size="3"&gt; por Vincent Rijmen y Joan Daemen, fue elegido como ganador. Aún no es un estándar, pero es de amplia aceptación a nivel mundial. &lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-FAMILY:Calibri;"&gt;&lt;font size="3"&gt;En nuestra demo utilizaremos el algoritmo AES. &lt;/font&gt;&lt;i&gt;&lt;font size="3"&gt;.NET&lt;/font&gt;&lt;/i&gt;&lt;font size="3"&gt; provee implementaciones de AES, DES y TripleDES entre otros. &lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;El algoritmo más seguro hoy el AES, aunque 3DES también es muy seguro. Este último se utiliza cuando hay necesidad de compatibilidad. AES 128 es aproximadamente 15% más rápido que DES, y AES 256 sigue siendo más rápido que DES. &lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Cualquiera de estos algoritmos utiliza los siguientes dos elementos; ninguno de los dos debe pasarse por alto ni subestimar su importancia: &lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-FAMILY:Calibri;"&gt;&lt;b&gt;&lt;font size="3"&gt;IV (Vector de inicialización)&lt;/font&gt;&lt;/b&gt;&lt;font size="3"&gt;&lt;br /&gt;Esta cadena se utiliza para empezar cada proceso de encriptación. Un error común es utilizar la misma cadena de inicialización en todas las encriptaciones. En ese caso, el resultado de las encriptaciones es similar, pudiendo ahorrarle mucho trabajo a un &lt;/font&gt;&lt;i&gt;&lt;font size="3"&gt;hacker&lt;/font&gt;&lt;/i&gt;&lt;font size="3"&gt; en el desciframiento de los datos. Tiene 16 &lt;/font&gt;&lt;i&gt;&lt;font size="3"&gt;bytes&lt;/font&gt;&lt;/i&gt;&lt;font size="3"&gt; de largo. Puedes encontrar más información acerca de IV en&lt;/font&gt;&lt;a href="http://www.atrevido.net/blog/PermaLink.aspx?guid=6136ce81-9fa1-4995-bb3e-15bc5f1f5899"&gt;&lt;font size="3"&gt; http://www.atrevido.net/blog/PermaLink.aspx?guid=6136ce81-9fa1-4995-bb3e-15bc5f1f5899&lt;/font&gt;&lt;/a&gt;&lt;font size="3"&gt;. &lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-FAMILY:Calibri;"&gt;&lt;i&gt;&lt;b&gt;&lt;font size="3"&gt;Key&lt;/font&gt;&lt;/b&gt;&lt;/i&gt;&lt;b&gt;&lt;font size="3"&gt; (llave)&lt;/font&gt;&lt;/b&gt;&lt;font size="3"&gt;&lt;br /&gt;Esta es la principal información para encriptar y desencriptar en los algoritmos simétricos. Toda la seguridad del sistema depende de dónde esté esta llave, cómo esté compuesta y quién tiene acceso. El largo de las llaves depende del algoritmo. Al final del documento se darán algunas recomendaciones para el almacenamiento, generación y rotación de llaves.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table class="" cellspacing="0" cellpadding="0"&gt;

&lt;tr&gt;
&lt;td class=""&gt;
&lt;table class="" cellspacing="0" cellpadding="5"&gt;

&lt;tr align="left"&gt;
&lt;td class=""&gt;
&lt;div style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;" align="center"&gt;&lt;b&gt;&lt;font color="#ffffff"&gt;Algoritmo&lt;/font&gt;&lt;/b&gt;&lt;/div&gt;&lt;/td&gt;
&lt;td class=""&gt;
&lt;div align="center"&gt;&lt;b&gt;&lt;font color="#ffffff"&gt;&lt;span&gt;&lt;span style="FONT-FAMILY:Calibri;"&gt;&lt;font size="3"&gt;Largos válidos (&lt;/font&gt;&lt;i&gt;&lt;font size="3"&gt;bits)&lt;/font&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/b&gt;&lt;/div&gt;&lt;/td&gt;
&lt;td class=""&gt;
&lt;div align="center"&gt;&lt;b&gt;&lt;font color="#ffffff"&gt;&lt;span&gt;&lt;span style="FONT-FAMILY:Calibri;"&gt;&lt;font size="3"&gt;Largo por defecto (&lt;/font&gt;&lt;i&gt;&lt;font size="3"&gt;bits)&lt;/font&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/b&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr align="left"&gt;
&lt;td class="" style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;DES&lt;/td&gt;
&lt;td class="" style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;64&lt;/td&gt;
&lt;td class=""&gt;&lt;span style="FONT-FAMILY:Calibri;"&gt;&lt;font size="3"&gt;64 (8 &lt;/font&gt;&lt;i&gt;&lt;font size="3"&gt;bytes&lt;/font&gt;&lt;/i&gt;&lt;font size="3"&gt;)&lt;/font&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr align="left"&gt;
&lt;td class="" style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;TripleDES&lt;/td&gt;
&lt;td class="" style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;128, 192&lt;/td&gt;
&lt;td class=""&gt;&lt;span style="FONT-FAMILY:Calibri;"&gt;&lt;font size="3"&gt;192 (24 &lt;/font&gt;&lt;i&gt;&lt;font size="3"&gt;bytes&lt;/font&gt;&lt;/i&gt;&lt;font size="3"&gt;)&lt;/font&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr align="left"&gt;
&lt;td class="" style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;i&gt;Rijndael&lt;/i&gt;&lt;/td&gt;
&lt;td class="" style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;128, 192, 256&lt;/td&gt;
&lt;td class=""&gt;&lt;span style="FONT-FAMILY:Calibri;"&gt;&lt;font size="3"&gt;256 (32 &lt;/font&gt;&lt;i&gt;&lt;font size="3"&gt;bytes&lt;/font&gt;&lt;/i&gt;&lt;font size="3"&gt;)&lt;/font&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;&lt;span style="FONT-FAMILY:Calibri;"&gt;&lt;font size="3"&gt;Veamos ahora nuestra aplicación y cómo funciona para encriptación y desencriptación con algoritmos simétricos, específicamente &lt;/font&gt;&lt;i&gt;&lt;font size="3"&gt;Rijndael&lt;/font&gt;&lt;/i&gt;&lt;font size="3"&gt; (Ver figura 3): &lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p align="center"&gt;&lt;span style="FONT-FAMILY:Calibri;"&gt;&lt;font size="3"&gt;&lt;br /&gt;&lt;img height="392" src="http://msmvps.com/blogs/pmackay/mtjnet/mtjnet-art216-img03-482x392.jpg" width="482" alt="" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/font&gt;&lt;b&gt;&lt;font size="3"&gt;Figura 3&lt;/font&gt;&lt;/b&gt;&lt;font size="3"&gt;: Resultado de la encriptación con &lt;/font&gt;&lt;i&gt;&lt;font size="3"&gt;Rijndael&lt;/font&gt;&lt;/i&gt;&lt;font size="3"&gt; aplicado sobre una imagen y texto&lt;/font&gt;&lt;/span&gt;.&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Lo primero que debemos hacer es especificar una llave de encriptación. Una cadena de texto se utiliza en el ejemplo. En la caja de más abajo se puede ingresar el texto que se desea encriptar. Luego de presionar &amp;quot;Encriptar&amp;quot; se obtiene el resultado de la encriptación en la caja del medio, y como es de esperarse, presionando &amp;quot;DesEncriptar&amp;quot; se obtiene el texto desencriptado en la última caja de texto. &lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Si revisamos el código fuente que realiza la encriptación y desencriptación, encontraremos algo de mayor complejidad con respecto las transformaciones anteriormente vistas.&lt;/p&gt;
&lt;table class="" cellspacing="0" cellpadding="0" bgcolor="lightgrey"&gt;

&lt;tr&gt;
&lt;td class=""&gt;
&lt;p style="FONT-FAMILY:Calibri;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;public&lt;/span&gt;&lt;span style="FONT-SIZE:12pt;COLOR:blue;"&gt; class&lt;/span&gt;&lt;font size="3"&gt; MiRijndael&lt;br /&gt;&lt;/font&gt;{&lt;font size="3"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;span style="FONT-SIZE:12pt;COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE:12pt;COLOR:blue;"&gt;static&lt;/span&gt; &lt;span style="FONT-SIZE:12pt;COLOR:blue;"&gt;byte&lt;/span&gt;&lt;font size="3"&gt;[] Encriptar(&lt;/font&gt;&lt;span style="FONT-SIZE:12pt;COLOR:blue;"&gt;string&lt;/span&gt;&lt;font size="3"&gt; strEncriptar, &lt;/font&gt;&lt;span style="FONT-SIZE:12pt;COLOR:blue;"&gt;byte&lt;/span&gt;&lt;font size="3"&gt;[] bytPK)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Rijndael miRijndael = Rijndael.Create();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;span style="FONT-SIZE:12pt;COLOR:blue;"&gt;byte&lt;/span&gt;&lt;font size="3"&gt;[] encrypted = &lt;/font&gt;&lt;span style="FONT-SIZE:12pt;COLOR:blue;"&gt;null&lt;/span&gt;;&lt;font size="3"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;span style="FONT-SIZE:12pt;COLOR:blue;"&gt;byte&lt;/span&gt;&lt;font size="3"&gt;[] returnValue = &lt;/font&gt;&lt;span style="FONT-SIZE:12pt;COLOR:blue;"&gt;null&lt;/span&gt;;&lt;font size="3"&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;span style="FONT-SIZE:12pt;COLOR:blue;"&gt;try&lt;/span&gt;&lt;font size="3"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; miRijndael.Key =&amp;nbsp; bytPK;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; miRijndael.GenerateIV();&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;span style="FONT-SIZE:12pt;COLOR:blue;"&gt;byte&lt;/span&gt;&lt;font size="3"&gt;[] toEncrypt =&amp;nbsp; System.Text.Encoding.UTF8.GetBytes(strEncriptar);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; encrypted = (miRijndael.CreateEncryptor()).TransformFinalBlock(toEncrypt, 0, toEncrypt.Length);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; returnValue = &lt;/font&gt;&lt;span style="FONT-SIZE:12pt;COLOR:blue;"&gt;new&lt;/span&gt; &lt;span style="FONT-SIZE:12pt;COLOR:blue;"&gt;byte&lt;/span&gt;&lt;font size="3"&gt;[miRijndael.IV.Length + encrypted.Length];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; miRijndael.IV.CopyTo(returnValue, 0);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; encrypted.CopyTo(returnValue, miRijndael.IV.Length);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;span style="FONT-SIZE:12pt;COLOR:blue;"&gt;catch&lt;/span&gt;&lt;font size="3"&gt; { }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;span style="FONT-SIZE:12pt;COLOR:blue;"&gt;finally&lt;/span&gt;&lt;font size="3"&gt; { miRijndael.Clear(); }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&am