<?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.5 SP2 (Build: 40407.4157)</generator><item><title>Llamar o no a GC.Collect directamente</title><link>http://msmvps.com/blogs/pmackay/archive/2009/02/22/post34.aspx</link><pubDate>Sun, 22 Feb 2009 16:22:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1673434</guid><dc:creator>pmackay</dc:creator><slash:comments>0</slash:comments><comments>http://msmvps.com/blogs/pmackay/archive/2009/02/22/post34.aspx#comments</comments><description>&lt;p&gt;&lt;span style="background-color:#008000;color:#ffffff;"&gt;Hace&lt;/span&gt; ya un tiempo publiqu&amp;eacute; un post donde hablaba de liberaci&amp;oacute;n de memoria en c&amp;oacute;digo manejado, y c&amp;oacute;mo ayudar a qui&amp;eacute;n es nuevo en .net y le dijeron que la memoria se liberaba sola. En &amp;eacute;ste, hac&amp;iacute;a una aclaraci&amp;oacute;n, la cual sigo manteniendo hasta ahora. Esta dice relaci&amp;oacute;n con el llamar o no a el metodo &lt;i&gt;collect&lt;/i&gt; del garbage collector (GC.Collect()).&lt;/p&gt;
&lt;p&gt;En esa oportunidad dec&amp;iacute;a que uno jam&amp;aacute;s deber&amp;iacute;a llamar al recolector de memoria manualmente, sino dejar que la recolecci&amp;oacute;n se hiciera en su tiempo, permitiendo que el garbage collector se adiestre s&amp;oacute;lo. Tambi&amp;eacute;n abr&amp;iacute;a la posibilidad de que alguien diera una buena justificaci&amp;oacute;n para hacerlo. Hasta el d&amp;iacute;a de hoy no hab&amp;iacute;a dado con ninguna, hasta ahora. &lt;i&gt;Hago hincapi&amp;eacute; en que no me creo ni soy due&amp;ntilde;o de la verdad, pero me baso en lo que veo y leo d&amp;iacute;a a d&amp;iacute;a&lt;/i&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Podcast&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Estando suscrito a podcasts, rss y cuanta informaci&amp;oacute;n podamos y creamos que vamos a ser capaces de digerir en alg&amp;uacute;n momento, algunos fueron recibiendo polvo hasta que un largo viaje arriba de un avi&amp;oacute;n me permiti&amp;oacute; escucharlos, en mi &lt;a target="_self" href="http://www.zune.net" title="Zune"&gt;Zune&lt;/a&gt; :). Si, tengo un Zune, igual que muy poca gente en este mundo porque nadie la conoce. Bueno, volvamos al grano.&lt;/p&gt;
&lt;p&gt;El podcast pertenece a la serie de &lt;a target="_blank" href="http://channel9.msdn.com/shows/ARCast.TV/" title="Arcast TV"&gt;arcast.tv&lt;/a&gt;, el t&amp;iacute;tulo de &amp;eacute;ste no era muy atractivo, no as&amp;iacute; la descripci&amp;oacute;n. &lt;/p&gt;
&lt;p&gt;El t&amp;iacute;tulo dec&amp;iacute;a &amp;quot;Steve Michelotti of e.imagination on High Performance Web Solutions&amp;quot;. Al igual que muchos, tu seguramente habr&amp;aacute;s encontrado documentaci&amp;oacute;n o podcasts con t&amp;iacute;tulos impresionantes, que terminaban siendo una recopilaci&amp;oacute;n de recomendaciones que puedes encontrar en cualquier buscador, utilizando tres palabras como web, performance y .net.&lt;/p&gt;
&lt;p&gt;La descripci&amp;oacute;n por otra parte, detallaba con lujo de que se trataba. El tema principal era problemas con el recolector de basura en arquitecturas de 64 bits. No voy a incluir ac&amp;aacute; la descripci&amp;oacute;n porque no podr&amp;iacute;a justificar el contenido de lo que escribir&amp;eacute; ahora y perder&amp;iacute;a la gracia. &lt;/p&gt;
&lt;p&gt;Si el ingl&amp;eacute;s no te abandona, te recomiendo que veas el podcast, como otros tambi&amp;eacute;n en el mismo sitio. El de RESTful services est&amp;aacute; muy bueno, al menos para los que creemos en REST y sus cualidades. Si ves el podcast, puedes evitar seguir leyendo &amp;eacute;sto.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&amp;iquest;Entonces?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Si no vas a ver el podcast y sigues ac&amp;aacute;, te cuento de qu&amp;eacute; se trata. No har&amp;eacute; una traducci&amp;oacute;n literal porque no tendr&amp;iacute;a sentido, sino algo donde explique los puntos y complemente la informaci&amp;oacute;n. &lt;/p&gt;
&lt;p&gt;Mencionaba hace un rato que el garbage collector se adiestra autom&amp;aacute;ticamente de acuerdo al patr&amp;oacute;n de petici&amp;oacute;n de memoria de tu aplicaci&amp;oacute;n (&lt;i&gt;allocation pattern&lt;/i&gt; en ingl&amp;eacute;s). Para el caso de el sitio mencionado, varios problemas sacud&amp;iacute;an el d&amp;iacute;a a d&amp;iacute;a, todos relacionados con la petici&amp;oacute;n y liberaci&amp;oacute;n de memoria. Veamos cada uno punto a punto y c&amp;oacute;mo los fueron tratando.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Gran cantidad de objetos creados en memoria&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;La aplicaci&amp;oacute;n era capaz de crear miles, millones de objetos en breve tiempo, los cuales eran descartados una vez que se dejaban de usar. Esto, en general, es esperable en cualquier aplicaci&amp;oacute;n. Los objetos se crean, se usan y luego se le dejan al GC para que reclame la memoria. El problema de ellos es que creaban muchos, MUCHOS objetos, aumentando la administraci&amp;oacute;n de memoria y disparando la recolecci&amp;oacute;n de basura con una frecuencia m&amp;aacute;s breve. Si no haz visto el post de &lt;a target="_blank" href="http://msmvps.com/blogs/pmackay/archive/2007/04/30/post0b.aspx"&gt;adiestramiento del GC&lt;/a&gt;, te lo recomiendo para clarificar este punto.&lt;/p&gt;
&lt;p&gt;&amp;iquest;C&amp;oacute;mo mitigaron el problema?, f&amp;aacute;cil, o ni tanto. Reutilizando objetos en vez de dej&amp;aacute;rselos al GC para que liberara la memoria utilizada. Debo reconocer que cuando lo escuchaba, me costaba asumir que era una opci&amp;oacute;n que alguna vez podr&amp;iacute;a considerar debido a la cantidad de trabajo que involucra. De esta forma, se crean menos objetos y se destruyen menos. Por lo tanto, menos presi&amp;oacute;n al GC.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&amp;iquest;Cu&amp;aacute;l es el problema con el GC?&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Mmm, en teor&amp;iacute;a, ninguno. En la pr&amp;aacute;ctica, debido a que el espacio de memoria virtual de un proceso de 64 bits es muy grande, en d&amp;oacute;nde grande significa aproximadamente 8TB de espacio de memoria virtual en modo usuario y 8TB en modo kernel (con diferencias leves entre IA64 y x64), los bloques de memoria manejados por el garbage collector pueden ser muchos m&amp;aacute;s que en una arquitectura de 32 bits, donde los espacios de memoria eran 2GB para usuario y 2GB para kernel.&lt;/p&gt;
&lt;p&gt;Como los bloques son muchos m&amp;aacute;s , para el caso de la aplicaci&amp;oacute;n en cuesti&amp;oacute;n, si el GC deb&amp;iacute;a hacer una recoleci&amp;oacute;n completa, es decir, incluir las 3 generaciones y el &lt;i&gt;heap&lt;/i&gt; de objetos grandes (&lt;i&gt;Large Object Heap&lt;/i&gt; o LOH en ingl&amp;eacute;s), esta pod&amp;iacute;a tomar entre 5 y 8 segundos en completarse. Para recolecciones de la generaci&amp;oacute;n 0 y 1, no es un problema porque ambas generaciones estan un &amp;uacute;nico segmento, que por lo general no supera los 64 MBs.&lt;/p&gt;
&lt;p&gt;Es importante rescatar que mientras se realiza una recolecci&amp;oacute;n de memoria, todos los hilos que est&amp;aacute;n ejecutando c&amp;oacute;digo manejado son detenidos. Esto impactaba sev&amp;eacute;ramente en el SLA (Contrato de nivel servicio) de ellos. Si cada cierto tiempo se debe &amp;quot;detener&amp;quot; un servidor entre 5 y 8 segundos, ser&amp;aacute; dificil poder cumplir con un SLA de 99,99%.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Otras acciones&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Entonces, a la reutilizaci&amp;oacute;n de objetos mencionada, se le agreg&amp;oacute; adem&amp;aacute;s la verificaci&amp;oacute;n que tanto operaciones de &lt;i&gt;boxing&lt;/i&gt; como &lt;i&gt;unboxing&lt;/i&gt; fuesen m&amp;iacute;nimas en el c&amp;oacute;digo. &lt;i&gt;Boxing&lt;/i&gt; y &lt;i&gt;unboxing&lt;/i&gt; se refieren a convertir un objeto de un tipo espec&amp;iacute;fico (de tipo valor) al tipo &lt;i&gt;object&lt;/i&gt; y viceversa. Esto ocurre generalmente fuera de nuestra vista, cuando utilizamos funciones o tipos que reciben object en vez del tipo espec&amp;iacute;fico. En el &lt;a target="_blank" href="http://blog.cumps.be/boxing-unboxing-in-net/"&gt;siguiente post&lt;/a&gt; se muestra c&amp;oacute;mo detectar y minimizar este patr&amp;oacute;n de uso.&lt;/p&gt;
&lt;p&gt;Otra acci&amp;oacute;n para minimizar el problema del consumo de memoria, fue utilizare &lt;i&gt;object pooling&lt;/i&gt;, funcionalidad generalmente utilizada para mantener conexiones a la base de datos sin ser destruidas, con el fin de minimizar la creaci&amp;oacute;n y destrucci&amp;oacute;n de los objetos, proceso que ya sabemos es costoso.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&amp;iquest;D&amp;oacute;nde entra GC.Collect y el llamado de forma expl&amp;iacute;cita?&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Habiendo minimizado la creaci&amp;oacute;n y destrucci&amp;oacute;n de objetos, el problema continuaba ocurriendo en menor medida, pero cuando ocurr&amp;iacute;a, nuevamente se sufr&amp;iacute;a de varios segundos sin servicio.&lt;/p&gt;
&lt;p&gt;Implementaron entonces un mecanismo de &lt;i&gt;broadcasting&lt;/i&gt; para la aplicaci&amp;oacute;n, con el que se informaba del estado de un servidor, a todas las aplicaciones corriendo en los servidores que compon&amp;iacute;an la capa de aplicaci&amp;oacute;n.&lt;/p&gt;
&lt;p&gt;Cada cierto per&amp;iacute;odo de tiempo, y cuando ya &amp;quot;se cre&amp;iacute;a&amp;quot; que podr&amp;iacute;a ocurrir una recolecci&amp;oacute;n de memoria completa en una aplicaci&amp;oacute;n del servidor X, &amp;eacute;sta le avisaba a todas las aplicaciones de los servidores restantes que iba a recolectar basura, y que por lo tanto no le fueran enviados requerimientos. Luego, cuando estaba &amp;quot;fuera de l&amp;iacute;nea&amp;quot;, llamaba manualmente a &lt;i&gt;GC.Collect&lt;/i&gt; y una vez finalizada la recolecci&amp;oacute;n, avisaba a las otras aplicaciones que ya estaba &amp;quot;en l&amp;iacute;nea&amp;quot;. &lt;/p&gt;
&lt;p&gt;Si bien la soluci&amp;oacute;n ayuda a mitigar el problema, se basa en la creencia (y esperanza) de que pronto ser&amp;aacute; recolectada la memoria, esto, con el fin de actuar antes y evitar el impacto de quedar fuera por varios segundos. Sin embargo, ya sabemos que la recolecci&amp;oacute;n ocurre de forma no deterministica. S&amp;oacute;lo el GC sabe cu&amp;aacute;ndo ser&amp;aacute; recolectada la memoria... hasta ahora.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;... Hasta ahora ...&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;La ayuda final que le da el toque de elegancia al modelo de ellos, (que ya lo ten&amp;iacute;a, para ser justos), vino de la persona que desarrolla el GC (Maoni Stephens). Ella ayud&amp;oacute; con la implementaci&amp;oacute;n de una funcionalidad que permite, como aplicaci&amp;oacute;n, ser notificado con un margen de tiempo especificable por uno, cu&amp;aacute;ndo podr&amp;iacute;a ocurrir la recolecci&amp;oacute;n de basura, permitiendoles a ellos no tener que &amp;quot;adivinar&amp;quot; o &amp;quot;creer&amp;quot; cuando ocurrir&amp;aacute; la recolecci&amp;oacute;n, si no que tener certeza absoluta.&lt;/p&gt;
&lt;p&gt;Esta nueva funcionalidad, m&amp;aacute;s la implementaci&amp;oacute;n del mecanismo de broadcasting, de puesta y sacada de l&amp;iacute;nea de las aplicaciones, se puede minimizar totalmente el impacto de &amp;eacute;stas.&lt;/p&gt;
&lt;p&gt;La funcionalidad del GC la pueden ver en el &lt;a target="_blank" href="http://msdn.microsoft.com/es-es/library/system.gc_members.aspx"&gt;siguiente articulo de MSDN&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Al menos para m&amp;iacute;, este es el primer caso donde veo que el llamado de GC.Collect() de forma manual es la soluci&amp;oacute;n a alg&amp;uacute;n problema espec&amp;iacute;fico.&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=1673434" 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></item><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>3</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>1</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>8</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>1</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>3</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/29/post28.aspx</link><pubDate>Thu, 29 Nov 2007 22:00:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1436186</guid><dc:creator>pmackay</dc:creator><slash:comments>6</slash:comments><comments>http://msmvps.com/blogs/pmackay/archive/2007/11/29/post28.aspx#comments</comments><description>&lt;h4 style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Aclaraci&amp;oacute;n&lt;/h4&gt;
&lt;p style="FONT-SIZE:12pt;COLOR:#cc3300;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;El siguiente contenido apareci&amp;oacute; publicado en la revista MTJ.NET en MSDN en espa&amp;ntilde;ol en el a&amp;ntilde;o 2005, en partes I y II. Debido a que la revista MTJ.NET no est&amp;aacute; al aire hoy, he optado por lanzarlo al aire nuevamente desde mi blog en un s&amp;oacute;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;span style="font-size:small;"&gt;C&amp;oacute;digo fuente disponible &lt;/span&gt;&lt;a target="_blank" href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/pmackay.Archivos/Desmitificando-la-Encriptaci_F300_n-_2800_c_F300_digo_2900_.zip"&gt;&lt;span style="font-size:small;"&gt;aqu&amp;iacute;&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:small;"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h4&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Introducci&amp;oacute;n&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Cuando es necesario darle seguridad a ciertos datos de nuestra aplicaci&amp;oacute;n, y buscamos informaci&amp;oacute;n en el &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Web&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; que nos permita lograrlo, es normal que hablemos (o leamos) de encriptaci&amp;oacute;n, y que irremediablemente salgan a la luz palabras tales como algoritmos sim&amp;eacute;tricos, asim&amp;eacute;tricos y &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Hash&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;. Estos t&amp;eacute;rminos pueden generar temor o dar la sensaci&amp;oacute;n de ser complejos. La motivaci&amp;oacute;n de este documento es mostrar qu&amp;eacute; es la encriptaci&amp;oacute;n sin necesidad de profundizar en c&amp;oacute;mo funciona un algoritmo internamente; y tambi&amp;eacute;n indicar las malas pr&amp;aacute;cticas que se realizan popularmente. Se revisar&amp;aacute; adem&amp;aacute;s la forma correcta de utilizar los algoritmos de encriptaci&amp;oacute;n, d&amp;oacute;nde se deben usar y d&amp;oacute;nde no.&lt;/span&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&amp;oacute;n y a que es preferible realizar todas las explicaciones correspondientes, fue necesario dividir el documento en dos partes. Lo que contendr&amp;aacute; cada parte est&amp;aacute; detallado en el siguiente &amp;iacute;ndice.&lt;/p&gt;
&lt;h4&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Agradecimientos&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Antes de comenzar deseo agradecer tanto el apoyo de Mike Giagnocavo como el de la informaci&amp;oacute;n disponible en su &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;blog&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; (&lt;/span&gt;&lt;a href="http://www.atrevido.net/"&gt;&lt;span style="font-size:small;"&gt;http://www.atrevido.net/&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:small;"&gt;). Sin sus consejos y correcciones, los ejemplos de este documento y la demostraci&amp;oacute;n no habr&amp;iacute;an quedado de excelente calidad y listos para utilizar. &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h4&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Introducci&amp;oacute;n, alcance y preguntas iniciales&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&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&amp;oacute;n y dedicaci&amp;oacute;n necesarias. Podemos formular las siguientes preguntas b&amp;aacute;sicas y es probable que encontremos falencias de seguridad que pueden comprometer a nuestro sistema: &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&amp;iquest;Se est&amp;aacute; almacenando la informaci&amp;oacute;n cr&amp;iacute;tica de forma segura? &lt;/li&gt;
&lt;li style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&amp;iquest;Qu&amp;eacute; entendemos por seguro? &lt;/li&gt;
&lt;li style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Si se est&amp;aacute; encriptando, &amp;iquest;Qu&amp;eacute; algoritmo se est&amp;aacute; utilizando? &lt;/li&gt;
&lt;li style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&amp;iquest;Se permite la desencriptaci&amp;oacute;n de datos que no debieran poder desencriptarse? &lt;/li&gt;
&lt;li style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&amp;iquest;C&amp;oacute;mo est&amp;aacute; realiz&amp;aacute;ndose la encriptaci&amp;oacute;n? &lt;/li&gt;
&lt;/ul&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Adicionalmente, podemos complementar con preguntas m&amp;aacute;s complejas:&lt;/p&gt;
&lt;ul&gt;
&lt;li style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&amp;iquest;D&amp;oacute;nde est&amp;aacute;n almacenadas la o las llaves? &lt;/li&gt;
&lt;li style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&amp;iquest;Con qu&amp;eacute; frecuencia se cambian las llaves? &lt;/li&gt;
&lt;li style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&amp;iquest;C&amp;oacute;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;&amp;iquest;Con qu&amp;eacute; 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&amp;aacute;sicas no sean respondidas adecuadamente. Si esto es as&amp;iacute;, ser&amp;iacute;a recomendable hacer una revisi&amp;oacute;n de los criterios y metodolog&amp;iacute;as que se est&amp;aacute;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: &amp;iquest;Qu&amp;eacute; le suceder&amp;iacute;a al negocio si alguien accediese a cualquiera de los datos privados del sistema? &amp;iquest;Se ver&amp;aacute; comprometida la seguridad con hechos como &amp;eacute;ste? De seguro, en ese momento el pensamiento ser&amp;iacute;a que valdr&amp;iacute;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&amp;eacute;todos que existen para proteger tanto el almacenamiento como el env&amp;iacute;o de la informaci&amp;oacute;n. Este documento NO tiene como intenci&amp;oacute;n ser un manual de seguridad. Esto es lo m&amp;iacute;nimo que debe tener una organizaci&amp;oacute;n para no estar al descubierto en sus procesos. Se debe entender que existen libros dedicados a la seguridad. Aqu&amp;iacute; se est&amp;aacute; danto el puntapi&amp;eacute; 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&amp;oacute;nde almacenar sus llaves, los criterios de cambio de llaves y tambi&amp;eacute;n los lugares donde almacenar&amp;aacute; la informaci&amp;oacute;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&amp;oacute;n de los algoritmos y los distintos tipos que existen. &lt;/p&gt;
&lt;h4&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Definici&amp;oacute;n de algoritmos&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Como se mencion&amp;oacute; con anterioridad, existen distintos tipos de algoritmos de encriptaci&amp;oacute;n, pero algo que no se ha mencionado hasta ahora son los &amp;ldquo;algoritmos&amp;rdquo; que se cree que encriptan, pero que no hacen nada m&amp;aacute;s que transformar texto (o informaci&amp;oacute;n). El objetivo de hacer esta distinci&amp;oacute;n es mostrar algunas malas pr&amp;aacute;cticas que se cometen, pensando que cualquier algoritmo que cambia de cierta forma un texto, est&amp;aacute; realizando encriptaci&amp;oacute;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&amp;aacute; hablando de encriptaci&amp;oacute;n, se revisar&amp;aacute;n tambi&amp;eacute;n los algoritmos que han sido construidos con distintos fines y que est&amp;aacute;n agrupados en distintas categor&amp;iacute;as. &amp;iquest;Cu&amp;aacute;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&amp;oacute;lo uno de estos algoritmos, como tambi&amp;eacute;n casos en los que debe utilizarse algoritmos de m&amp;aacute;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&amp;oacute;n es una serie de car&amp;aacute;cteres, de determinado largo, que se utiliza para encriptar y desencriptar la informaci&amp;oacute;n que se quiere proteger. El largo de la llave depende del algoritmo. Existen llaves privadas y p&amp;uacute;blicas, que ser&amp;aacute;n detalladas m&amp;aacute;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;span style="font-size:small;"&gt;Escenario 1&lt;/span&gt;&lt;/strong&gt;&lt;span style="font-size:small;"&gt;: Necesito almacenar informaci&amp;oacute;n cr&amp;iacute;tica que deber&amp;aacute; poder descifrarse, y ser&amp;eacute; yo el &amp;uacute;nico que haga todo el proceso. Nadie m&amp;aacute;s tendr&amp;aacute; acceso a la llave con que se encriptar&amp;aacute; y desencriptar&amp;aacute; la informaci&amp;oacute;n. &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-family:Calibri;"&gt;&lt;strong&gt;&lt;span style="font-size:small;"&gt;Escenario 2&lt;/span&gt;&lt;/strong&gt;&lt;span style="font-size:small;"&gt;: Necesito que me env&amp;iacute;en informaci&amp;oacute;n cr&amp;iacute;tica que yo desencriptar&amp;eacute; posteriormente, pero necesito que las personas que me van a enviar informaci&amp;oacute;n pueden encriptarla libremente, pero no desencriptarla. En este caso, se deja disponible una llave p&amp;uacute;blica para que ellos encripten y yo tendr&amp;eacute; mi llave privada de encriptaci&amp;oacute;n en forma segura. &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-family:Calibri;"&gt;&lt;strong&gt;&lt;span style="font-size:small;"&gt;Escenario 3&lt;/span&gt;&lt;/strong&gt;&lt;span style="font-size:small;"&gt;: Necesito almacenar o enviar informaci&amp;oacute;n cr&amp;iacute;tica de forma segura, pero que no requerir&amp;aacute; ser desencriptada para su validaci&amp;oacute;n, o que es extremadamente importante verificar que no haya sido modificada en el camino. &lt;/span&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&amp;aacute;s comunes. Es probable que te preguntes para qu&amp;eacute; puede haber casos como el 3. Lo veremos m&amp;aacute;s adelante con ejemplos, destacando ventajas y desventajas. Los tres escenarios calzan con los algoritmos listados a continuaci&amp;oacute;n:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="font-family:Calibri;"&gt;&lt;strong&gt;&lt;span style="font-size:small;"&gt;Escenario 1&lt;/span&gt;&lt;/strong&gt;&lt;span style="font-size:small;"&gt;: Encriptaci&amp;oacute;n sim&amp;eacute;trica &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-family:Calibri;"&gt;&lt;strong&gt;&lt;span style="font-size:small;"&gt;Escenario 2&lt;/span&gt;&lt;/strong&gt;&lt;span style="font-size:small;"&gt;: Encriptaci&amp;oacute;n asim&amp;eacute;trica &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-family:Calibri;"&gt;&lt;strong&gt;&lt;span style="font-size:small;"&gt;Escenario 3&lt;/span&gt;&lt;/strong&gt;&lt;span style="font-size:small;"&gt;: &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Hash&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; de informaci&amp;oacute;n &lt;/span&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&amp;aacute;ctica que se utiliza m&amp;aacute;s de lo que debiera, que corresponde a la utilizaci&amp;oacute;n de &amp;ldquo;algoritmos&amp;rdquo; o mejor dicho, transformaciones del contenido.&lt;/p&gt;
&lt;h4&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Malas pr&amp;aacute;cticas o transformaciones&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Antes mencionamos que es com&amp;uacute;n escuchar o ver que se utilizan ciertas transformaciones como m&amp;eacute;todos de protecci&amp;oacute;n. Como la comparaci&amp;oacute;n se hace con el ojo humano, si se tiene una cadena de texto y se decide transformar aplic&amp;aacute;ndole un XOR o desplazando los &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;bytes&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;, el resultado de esa transformaci&amp;oacute;n nos produce el efecto de que est&amp;aacute; 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&amp;aacute;n los dos efectos mencionados reci&amp;eacute;n, XOR y Desplazamiento, y se ver&amp;aacute; que es efectivamente lo que hacen. El motivo de utilizar una imagen es para que nuestro ojo no se enga&amp;ntilde;e con las apariencias.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&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;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;bytes&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p align="center"&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;img width="482" src="http://msmvps.com/blogs/pmackay/mtjnet/mtjnet-art216-img01-482x392.jpg" height="392" alt="" /&gt;&lt;br /&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:small;"&gt;Figura 1&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:small;"&gt;.&lt;/span&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;span style="font-size:small;"&gt;Si se presiona Transformar, el resultado ser&amp;aacute; el que se muestra en la figura 2: &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p align="center"&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;img width="482" src="http://msmvps.com/blogs/pmackay/mtjnet/mtjnet-art216-img02-482-392.jpg" height="392" alt="" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:small;"&gt;Figura 2&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:small;"&gt;: Resultado de las transformaciones.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Como se puede apreciar, no se produce una encriptaci&amp;oacute;n sino s&amp;oacute;lo una transformaci&amp;oacute;n de los datos (m&amp;aacute;s adelante ver&amp;aacute;s c&amp;oacute;mo queda la imagen realmente encriptada). Este tipo de transformaciones no protege nuestra informaci&amp;oacute;n. Hagamos ahora las siguientes preguntas: &amp;iquest;Cu&amp;aacute;nta seguridad existe con estas transformaciones? &amp;iquest;Cu&amp;aacute;nto demorar&amp;aacute; un &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;hacker&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; en retransformar esto? El &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;hacker &lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;obtiene la respuesta en menos de lo que te toma a ti leer s&amp;oacute;lo esta l&amp;iacute;nea. Hacerle modificaciones a este &amp;ldquo;algoritmo&amp;rdquo; no sirve. La encriptaci&amp;oacute;n no es trivial de hacer, pero es mucho m&amp;aacute;s f&amp;aacute;cil de usar. M&amp;aacute;s adelante conocer&amp;aacute;s&amp;nbsp; la cantidad de a&amp;ntilde;os que estuvo estudi&amp;aacute;ndose el algoritmo &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Rijndael&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; o AES, para ser declarado vencedor. &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;El c&amp;oacute;digo que utilizamos para realizar la transformaci&amp;oacute;n XOR es el siguiente. El c&amp;oacute;digo de desplazamiento es muy similar. Este, al igual que todo el c&amp;oacute;digo del documento, est&amp;aacute; disponible en el archivo adjunto con este art&amp;iacute;culo. Por motivos que no corresponde explicar aqu&amp;iacute;, ya que no entran en el objetivo del documento, con la imagen que se est&amp;aacute; trabajando es necesario comenzar desde la posici&amp;oacute;n 34, ya que si se comienza desde el &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;byte&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; 0 transformando, el archivo BMP ya no es posible visualizarlo. &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Lo &amp;uacute;nico que hace este &amp;ldquo;algoritmo&amp;rdquo; es aplicar XOR a un arreglo de &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;bytes&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;. Para aplicarlo sobre texto lo &amp;uacute;nico que hay que hacer son las transformaciones de &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;bytes&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; a texto y viceversa. Como explicaci&amp;oacute;n sencilla de este proceso, podemos decir que lo que hace es tomar cada uno de los &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;bytes&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; y aplicarle un XOR (representado por el s&amp;iacute;mbolo &amp;quot;^&amp;quot; en el c&amp;oacute;digo). Un XOR corresponde al resultado de la comparaci&amp;oacute;n &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;bit&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; a &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;bit&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; de dos &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;bytes&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;. En este caso, un &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;byte&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; viene del texto a transformar y el otro del n&amp;uacute;mero 87 elegido al azar.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table bgcolor="#d3d3d3" cellpadding="0" cellspacing="0"&gt;

&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="font-size:12pt;color:#0000ff;"&gt;class&lt;/span&gt;&lt;span style="font-size:small;"&gt; TransformacionXOR&lt;br /&gt;&lt;/span&gt;{&lt;span style="font-size:small;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="font-size:12pt;color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="font-size:12pt;color:#0000ff;"&gt;int&lt;/span&gt;&lt;span style="font-size:small;"&gt; _XOR = 87;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="font-size:12pt;color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="font-size:12pt;color:#0000ff;"&gt;byte&lt;/span&gt;&lt;span style="font-size:small;"&gt;[] Codificar(&lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;byte&lt;/span&gt;&lt;span style="font-size:small;"&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;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;for&lt;/span&gt;&lt;span style="font-size:small;"&gt; (&lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;int&lt;/span&gt;&lt;span style="font-size:small;"&gt; _intPos = &lt;/span&gt;&lt;b&gt;&lt;span style="font-size:small;"&gt;34&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:small;"&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;/span&gt;&lt;span&gt;&lt;span style="font-size:small;"&gt;bytACodificar[_intPos] = (&lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;byte&lt;/span&gt;&lt;span style="font-size:small;"&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;/span&gt;&lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;return&lt;/span&gt;&lt;span style="font-size:small;"&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;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="font-size:12pt;color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="font-size:12pt;color:#0000ff;"&gt;byte&lt;/span&gt;&lt;span style="font-size:small;"&gt;[] DeCodificar(&lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;byte&lt;/span&gt;&lt;span style="font-size:small;"&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;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;for&lt;/span&gt;&lt;span style="font-size:small;"&gt; (&lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;int&lt;/span&gt;&lt;span style="font-size:small;"&gt; _intPos = &lt;/span&gt;&lt;b&gt;&lt;span style="font-size:small;"&gt;34&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:small;"&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;/span&gt;&lt;span&gt;&lt;span style="font-size:small;"&gt;bytADecodificar[_intPos] = (&lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;byte&lt;/span&gt;&lt;span style="font-size:small;"&gt;) (_XOR ^ bytADecodificar[_intPos]); &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="font-size:small;"&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;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;return&lt;/span&gt;&lt;span style="font-size:small;"&gt; bytADecodificar;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&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&amp;aacute;s debe utilizarse para proteger informaci&amp;oacute;n. No debe creerse que es XOR el responsable de esto. XOR es muy &amp;uacute;til en otros contextos, pero no se puede utilizar de esta forma. &lt;/p&gt;
&lt;blockquote&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;" class="txt-msdn-notas"&gt;&lt;em&gt;Nota: Antes de continuar, es muy importante aclarar lo siguiente. Si se va a proteger informaci&amp;oacute;n, el proceso DEBE realizarse a conciencia y con algoritmos probados. Adem&amp;aacute;s, se debe utilizar el algoritmo de la forma en que fue concebido. Implementaciones a medias, son tan in&amp;uacute;tiles como las transformaciones reci&amp;eacute;n vistas o como la no utilizaci&amp;oacute;n de &amp;eacute;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&amp;oacute;n. &lt;/p&gt;
&lt;h4&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Encriptaci&amp;oacute;n sim&amp;eacute;trica&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Cuando hablamos de encriptaci&amp;oacute;n y no de transformaci&amp;oacute;n, ya estamos adentr&amp;aacute;ndonos en temas de mayor protecci&amp;oacute;n, de algoritmos conocidos y seguridad real. El proceso de realizar una encriptaci&amp;oacute;n es complejo para ser entendido por nosotros mismos, pero no es limitante para conocer cu&amp;aacute;les son los pasos para utilizarlos y qu&amp;eacute; errores no se deben cometer.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Dentro de los algoritmos de encriptaci&amp;oacute;n sim&amp;eacute;trica podemos encontrar los siguientes, algunos m&amp;aacute;s seguros que otros.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;DES (&lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Digital Encryption Standard&lt;/span&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;span style="font-size:small;"&gt;Creado en 1975 con ayuda de la NSA (&lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;National Security Agency&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;); en 1982 se convirti&amp;oacute; en un est&amp;aacute;ndar. Utiliza una llave de 56 &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;bit&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;. En 1999 logr&amp;oacute; ser quebrado (violado) en menos de 24 horas por un servidor dedicado a eso. Esto lo calific&amp;oacute; como un algoritmo inseguro y con falencias reconocidas.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;3DES (&lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Three DES&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; o &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Triple DES&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&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;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;bits&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&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&amp;iacute;a es uno de los algoritmos sim&amp;eacute;tricos m&amp;aacute;s seguros.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;IDEA (&lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;International Data Encryption Algorithm&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;M&amp;aacute;s conocido como un componente de PGP (encriptaci&amp;oacute;n de &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;mails&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;), trabaja con llaves de 128 &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;bits&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;. Realiza procesos de &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;shift&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; y copiado y pegado de los 128 &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;bits&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;, dejando un total de 52 sub llaves de 16 &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;bits&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; cada una. Es un algoritmo m&amp;aacute;s r&amp;aacute;pido que el DES, pero al ser nuevo, a&amp;uacute;n no es aceptado como un est&amp;aacute;ndar, aunque no se le han encontrado debilidades a&amp;uacute;n. &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;AES (&lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Advanced Encryption Standard&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;Este fue el ganador del primer concurso de algoritmos de encriptaci&amp;oacute;n realizado por la NIST (&lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;National Institute of Standards and Technology&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;) en 1997. Despu&amp;eacute;s de 3 a&amp;ntilde;os de estudio y habiendo descartado a 14 candidatos, este algoritmo, tambi&amp;eacute;n conocido como &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Rijndael&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; por Vincent Rijmen y Joan Daemen, fue elegido como ganador. A&amp;uacute;n no es un est&amp;aacute;ndar, pero es de amplia aceptaci&amp;oacute;n a nivel mundial. &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;En nuestra demo utilizaremos el algoritmo AES. &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;.NET&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; provee implementaciones de AES, DES y TripleDES entre otros. &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;El algoritmo m&amp;aacute;s seguro hoy el AES, aunque 3DES tambi&amp;eacute;n es muy seguro. Este &amp;uacute;ltimo se utiliza cuando hay necesidad de compatibilidad. AES 128 es aproximadamente 15% m&amp;aacute;s r&amp;aacute;pido que DES, y AES 256 sigue siendo m&amp;aacute;s r&amp;aacute;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;span style="font-size:small;"&gt;IV (Vector de inicializaci&amp;oacute;n)&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;Esta cadena se utiliza para empezar cada proceso de encriptaci&amp;oacute;n. Un error com&amp;uacute;n es utilizar la misma cadena de inicializaci&amp;oacute;n en todas las encriptaciones. En ese caso, el resultado de las encriptaciones es similar, pudiendo ahorrarle mucho trabajo a un &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;hacker&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; en el desciframiento de los datos. Tiene 16 &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;bytes&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; de largo. Puedes encontrar m&amp;aacute;s informaci&amp;oacute;n acerca de IV en&lt;/span&gt;&lt;a href="http://www.atrevido.net/blog/PermaLink.aspx?guid=6136ce81-9fa1-4995-bb3e-15bc5f1f5899"&gt;&lt;span style="font-size:small;"&gt; http://www.atrevido.net/blog/PermaLink.aspx?guid=6136ce81-9fa1-4995-bb3e-15bc5f1f5899&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:small;"&gt;. &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;i&gt;&lt;b&gt;&lt;span style="font-size:small;"&gt;Key&lt;/span&gt;&lt;/b&gt;&lt;/i&gt;&lt;b&gt;&lt;span style="font-size:small;"&gt; (llave)&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;Esta es la principal informaci&amp;oacute;n para encriptar y desencriptar en los algoritmos sim&amp;eacute;tricos. Toda la seguridad del sistema depende de d&amp;oacute;nde est&amp;eacute; esta llave, c&amp;oacute;mo est&amp;eacute; compuesta y qui&amp;eacute;n tiene acceso. El largo de las llaves depende del algoritmo. Al final del documento se dar&amp;aacute;n algunas recomendaciones para el almacenamiento, generaci&amp;oacute;n y rotaci&amp;oacute;n de llaves.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table cellpadding="0" cellspacing="0"&gt;

&lt;tr&gt;
&lt;td&gt;
&lt;table cellpadding="5" cellspacing="0"&gt;

&lt;tr align="left"&gt;
&lt;td&gt;
&lt;div align="center" style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;b&gt;&lt;span style="color:#ffffff;"&gt;Algoritmo&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;div align="center"&gt;&lt;b&gt;&lt;span style="color:#ffffff;"&gt;&lt;span&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Largos v&amp;aacute;lidos (&lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;bits)&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;div align="center"&gt;&lt;b&gt;&lt;span style="color:#ffffff;"&gt;&lt;span&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Largo por defecto (&lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;bits)&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr align="left"&gt;
&lt;td style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;DES&lt;/td&gt;
&lt;td style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;64&lt;/td&gt;
&lt;td&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;64 (8 &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;bytes&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr align="left"&gt;
&lt;td style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;TripleDES&lt;/td&gt;
&lt;td style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;128, 192&lt;/td&gt;
&lt;td&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;192 (24 &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;bytes&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr align="left"&gt;
&lt;td style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;i&gt;Rijndael&lt;/i&gt;&lt;/td&gt;
&lt;td style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;128, 192, 256&lt;/td&gt;
&lt;td&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;256 (32 &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;bytes&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;)&lt;/span&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;span style="font-size:small;"&gt;Veamos ahora nuestra aplicaci&amp;oacute;n y c&amp;oacute;mo funciona para encriptaci&amp;oacute;n y desencriptaci&amp;oacute;n con algoritmos sim&amp;eacute;tricos, espec&amp;iacute;ficamente &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Rijndael&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; (Ver figura 3): &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p align="center"&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;img width="482" src="http://msmvps.com/blogs/pmackay/mtjnet/mtjnet-art216-img03-482x392.jpg" height="392" alt="" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:small;"&gt;Figura 3&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:small;"&gt;: Resultado de la encriptaci&amp;oacute;n con &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Rijndael&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; aplicado sobre una imagen y texto&lt;/span&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&amp;oacute;n. Una cadena de texto se utiliza en el ejemplo. En la caja de m&amp;aacute;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&amp;oacute;n en la caja del medio, y como es de esperarse, presionando &amp;quot;DesEncriptar&amp;quot; se obtiene el texto desencriptado en la &amp;uacute;ltima caja de texto. &lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Si revisamos el c&amp;oacute;digo fuente que realiza la encriptaci&amp;oacute;n y desencriptaci&amp;oacute;n, encontraremos algo de mayor complejidad con respecto las transformaciones anteriormente vistas.&lt;/p&gt;
&lt;table bgcolor="#d3d3d3" cellpadding="0" cellspacing="0"&gt;

&lt;tr&gt;
&lt;td&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:#0000ff;"&gt; class&lt;/span&gt;&lt;span style="font-size:small;"&gt; MiRijndael&lt;br /&gt;&lt;/span&gt;{&lt;span style="font-size:small;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="font-size:12pt;color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="font-size:12pt;color:#0000ff;"&gt;byte&lt;/span&gt;&lt;span style="font-size:small;"&gt;[] Encriptar(&lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;string&lt;/span&gt;&lt;span style="font-size:small;"&gt; strEncriptar, &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;byte&lt;/span&gt;&lt;span style="font-size:small;"&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;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;byte&lt;/span&gt;&lt;span style="font-size:small;"&gt;[] encrypted = &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;null&lt;/span&gt;;&lt;span style="font-size:small;"&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;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;byte&lt;/span&gt;&lt;span style="font-size:small;"&gt;[] returnValue = &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;null&lt;/span&gt;;&lt;span style="font-size:small;"&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;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;try&lt;/span&gt;&lt;span style="font-size:small;"&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;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;byte&lt;/span&gt;&lt;span style="font-size:small;"&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;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="font-size:12pt;color:#0000ff;"&gt;byte&lt;/span&gt;&lt;span style="font-size:small;"&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;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;catch&lt;/span&gt;&lt;span style="font-size:small;"&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;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;finally&lt;/span&gt;&lt;span style="font-size:small;"&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;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;return&lt;/span&gt;&lt;span style="font-size:small;"&gt; returnValue;&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;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="font-size:12pt;color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="font-size:12pt;color:#0000ff;"&gt;string&lt;/span&gt;&lt;span style="font-size:small;"&gt; Desencriptar(&lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;byte&lt;/span&gt;&lt;span style="font-size:small;"&gt;[] bytDesEncriptar, &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;byte&lt;/span&gt;&lt;span style="font-size:small;"&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;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;byte&lt;/span&gt;&lt;span style="font-size:small;"&gt;[] tempArray = &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="font-size:12pt;color:#0000ff;"&gt;byte&lt;/span&gt;&lt;span style="font-size:small;"&gt;[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;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;byte&lt;/span&gt;&lt;span style="font-size:small;"&gt;[] encrypted = &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="font-size:12pt;color:#0000ff;"&gt;byte&lt;/span&gt;&lt;span style="font-size:small;"&gt;[bytDesEncriptar.Length - 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;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;string&lt;/span&gt;&lt;span style="font-size:small;"&gt; returnValue = &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;string&lt;/span&gt;&lt;span style="font-size:small;"&gt;.Empty;&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;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;try&lt;/span&gt;&lt;span style="font-size:small;"&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;&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; Array.Copy(bytDesEncriptar, tempArray, tempArray.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; Array.Copy(bytDesEncriptar, tempArray.Length, encrypted, 0, 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; &lt;/span&gt;&lt;span style="FONT-SIZE:12pt;"&gt;miRijndael.IV = tempArray;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;span style="font-family:Calibri;"&gt;
&lt;p style="FONT-SIZE:12pt;" class="SourceCode"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="SourceCode"&gt;&lt;span style="FONT-SIZE:12pt;"&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 =&amp;nbsp; System.Text.Encoding.UTF8.GetString((miRijndael.CreateDecryptor()).TransformFinalBlock(encrypted, 0, encrypted.Length));&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="SourceCode"&gt;&lt;span style="FONT-SIZE:12pt;"&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;/span&gt;}&lt;span style="font-size:small;"&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;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;catch&lt;/span&gt;&lt;span style="font-size:small;"&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;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;finally&lt;/span&gt;&lt;span style="font-size:small;"&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;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;return&lt;/span&gt;&lt;span style="font-size:small;"&gt; returnValue;&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;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="font-size:12pt;color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="font-size:12pt;color:#0000ff;"&gt;byte&lt;/span&gt;&lt;span style="font-size:small;"&gt;[] Encriptar(&lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;string&lt;/span&gt;&lt;span style="font-size:small;"&gt; strEncriptar, &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;string&lt;/span&gt;&lt;span style="font-size:small;"&gt; strPK)&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;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;return&lt;/span&gt;&lt;span style="font-size:small;"&gt; Encriptar(strEncriptar, (&lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;new&lt;/span&gt;&lt;span style="font-size:small;"&gt; PasswordDeriveBytes(strPK, &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;null&lt;/span&gt;&lt;span style="font-size:small;"&gt;)).GetBytes(32));&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;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="font-size:12pt;color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="font-size:12pt;color:#0000ff;"&gt;string&lt;/span&gt;&lt;span style="font-size:small;"&gt; Desencriptar(&lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;byte&lt;/span&gt;&lt;span style="font-size:small;"&gt;[] bytDesEncriptar, &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;string&lt;/span&gt;&lt;span style="font-size:small;"&gt; strPK)&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;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;return&lt;/span&gt;&lt;span style="font-size:small;"&gt; Desencriptar(bytDesEncriptar, (&lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;new&lt;/span&gt;&lt;span style="font-size:small;"&gt; PasswordDeriveBytes(strPK, &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;null&lt;/span&gt;&lt;span style="font-size:small;"&gt;)).GetBytes(32));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;/table&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Explicar el funcionamiento del algoritmo no entra dentro del alcance de este documento y, siendo sincero, desconozco c&amp;oacute;mo funciona. Tampoco creo que sea necesario que nosotros sepamos c&amp;oacute;mo funcionan los algoritmos de encriptaci&amp;oacute;n. Lo importante es utilizarlos bien.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p class="txt-msdn-notas"&gt;&lt;span style="font-size:12pt;font-family:Calibri;"&gt;&lt;i&gt;Nota: Para obtener la llave del algoritmo, dado que una cadena de car&amp;aacute;cteres generada por un humano en un formulario es considerada poco variada debido a que los car&amp;aacute;cteres utilizados son pocos (a-&amp;gt;z, A-&amp;gt;Z, 0-&amp;gt;9), se le aplica un proceso de variaci&amp;oacute;n con la clase PasswordDeriveBytes y se le pide un resultado de 32 bytes. Esto nos retorna una llave con car&amp;aacute;cteres variados, ideal para la encriptaci&amp;oacute;n. PasswordDeriveBytes utiliza Hash para generar la salida. Hash se ver&amp;aacute; m&amp;aacute;s adelante.&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Volviendo al ejemplo, si se presiona &amp;quot;Encriptar&amp;quot; nuevamente, las veces que se desee, se ver&amp;aacute; que el resultado de la encriptaci&amp;oacute;n var&amp;iacute;a. &amp;iquest;Por qu&amp;eacute; sucede esto, si el resultado de la encriptaci&amp;oacute;n debiera ser el mismo? La variaci&amp;oacute;n en el resultado de una encriptaci&amp;oacute;n se produce por dos variantes en el proceso, el &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Key&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; (o llave de encriptaci&amp;oacute;n) y el IV (o vector de inicializaci&amp;oacute;n). En este caso se est&amp;aacute; utilizando el mismo &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Key&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; (expl&amp;iacute;cito en la caja de texto) pero el IV est&amp;aacute; variando todas las veces. &amp;iquest;Porqu&amp;eacute; var&amp;iacute;a el IV? &amp;iquest;Qu&amp;eacute; es el IV? &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;El IV o vector de inicializaci&amp;oacute;n es un concepto no entendido del todo, por que algunos creen que se puede encriptar &amp;ldquo;sin &amp;eacute;l&amp;rdquo;. El IV cumple un rol peque&amp;ntilde;o, pero muy importante. El &amp;uacute;nico motivo por el cual existe es para apoyar el proceso de encriptaci&amp;oacute;n, permitiendo exactamente que ocurra lo que se observ&amp;oacute; en la caja de texto, es decir,&amp;nbsp; la variaci&amp;oacute;n del resultado del proceso de encriptaci&amp;oacute;n. El IV no debe considerarse como una segunda llave, por que no lo es. Es una ayuda y por lo mismo, no es un dato que haya que esconder, si no que basta con almacenarlo para que cuando se vaya a desencriptar se utilice el mismo IV que se utiliz&amp;oacute; en la encriptaci&amp;oacute;n. En el ejemplo, el IV se retorna como parte del resultado de la encriptaci&amp;oacute;n y se genera cada vez que se realiza un encriptaci&amp;oacute;n. Su largo es de 16 &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;bytes&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; para el algoritmo de &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Rijndael&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;. &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;" class="txt-msdn-notas"&gt;&lt;em&gt;Nota: Utilizar siempre un mismo IV para no tener que almacenarlo es equivalente en seguridad a no utilizar encriptaci&amp;oacute;n. La seguridad mal implementada es m&amp;aacute;s insegura que no implementarla. &amp;iquest;Por que? Porque da la creencia de tener seguridad, y produce una confianza que es nociva. Si no tienes seguridad en tu aplicaci&amp;oacute;n, eso lo sabes y est&amp;aacute;s preocupado, pero si se tiene una seguridad mal implementada se cree que se tiene, pero no es as&amp;iacute;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p align="left" style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Con la implementaci&amp;oacute;n entregada en la demo, el IV est&amp;aacute; correctamente utilizado. En las im&amp;aacute;genes de la segunda parte se aplica el mismo algoritmo de encriptaci&amp;oacute;n, pero utilizando variaciones en el modo de ciframiento. En la segunda imagen se aplica el modo ECB y en la tercera CBC. Estos modos especifican al algoritmo c&amp;oacute;mo debe funcionar. El modo m&amp;aacute;s seguro, que tambi&amp;eacute;n es el modo por defecto es CBC.&lt;/p&gt;
&lt;p align="left" style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;El modo de ciframiento ECB no utiliza IV, por lo mismo no debe usarse como modo de ciframiento, a menos que sea necesario por compatibilidad. Esta es otra muestra de porqu&amp;eacute; es &amp;uacute;til el IV y porqu&amp;eacute; debe usarse, y que sucede con la encriptaci&amp;oacute;n cuando el IV no var&amp;iacute;a nunca.&lt;/p&gt;
&lt;p align="left" style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Es importante considerar que en los algoritmos sim&amp;eacute;tricos se utiliza la misma llave para encriptar y desencriptar. En los algoritmos asim&amp;eacute;tricos se ver&amp;aacute; que existen dos llaves, una p&amp;uacute;blica para encriptar y una privada para desencriptar.&lt;/p&gt;
&lt;h4&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Encriptaci&amp;oacute;n Asim&amp;eacute;trica&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;La encriptaci&amp;oacute;n asim&amp;eacute;trica permite que dos personas puedan enviarse informaci&amp;oacute;n encriptada, sin necesidad de compartir la llave de encriptaci&amp;oacute;n. Se utiliza una llave p&amp;uacute;blica para encriptar el texto y una llave privada para desencriptar. A pesar de que puede sonar extra&amp;ntilde;o que se encripte con la llave p&amp;uacute;blica y desencripte con la privada, el motivo para hacerlo es el siguiente: si alguien necesita que le env&amp;iacute;en la informaci&amp;oacute;n encriptada, deja disponible la llave p&amp;uacute;blica para que quienes le desean enviar algo lo encripten. Nadie puede desencriptar algo con la misma llave p&amp;uacute;blica. El &amp;uacute;nico que puede desencriptar es quien posea la llave privada, quien justamente es el que recibe la informaci&amp;oacute;n encriptada.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Los algoritmos de encriptaci&amp;oacute;n asim&amp;eacute;trica m&amp;aacute;s conocidos son:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;RSA (&lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Rivest, Shamir, Adleman&lt;/span&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-size:12pt;font-family:Calibri;"&gt;Creado en 1978, hoy es el algoritmo de mayor uso en encriptaci&amp;oacute;n asim&amp;eacute;trica. Tiene dificultades para encriptar grandes vol&amp;uacute;menes de informaci&amp;oacute;n, por lo que es usado por lo general en conjunto con algoritmos sim&amp;eacute;tricos. &lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style="font-family:Calibri;"&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Diffie-Hellman&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; (&amp;amp; &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Merkle&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;No es precisamente un algoritmo de encriptaci&amp;oacute;n sino un algoritmo para generar llaves p&amp;uacute;blicas y privadas en ambientes inseguros. &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;ECC (&lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Elliptical Curve Cryptography&lt;/span&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-size:12pt;font-family:Calibri;"&gt;Es un algoritmo que se utiliza poco, pero tiene importancia cuando es necesario encriptar grandes vol&amp;uacute;menes de informaci&amp;oacute;n. &lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;El tama&amp;ntilde;o de la llave es el siguiente:&lt;/p&gt;
&lt;table align="center" cellpadding="0" cellspacing="0"&gt;

&lt;tr&gt;
&lt;td&gt;
&lt;table cellpadding="5" cellspacing="0"&gt;

&lt;tr align="left"&gt;
&lt;td&gt;
&lt;div align="center" style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;b&gt;&lt;span style="color:#ffffff;"&gt;Algoritmo&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;div align="center"&gt;&lt;b&gt;&lt;span style="color:#ffffff;"&gt;&lt;span&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Largos v&amp;aacute;lidos (&lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;bits)&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;div align="center"&gt;&lt;b&gt;&lt;span style="color:#ffffff;"&gt;&lt;span&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Largo por defecto (&lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;bits)&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr align="left"&gt;
&lt;td style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;RSA&lt;/td&gt;
&lt;td style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;384 a 16.384 (incrementos de a 8)&lt;/td&gt;
&lt;td style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;1.024&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;span style="font-size:small;"&gt;Mientras m&amp;aacute;s larga sea la llave, m&amp;aacute;s seguro ser&amp;aacute;. La relaci&amp;oacute;n con los algoritmos sim&amp;eacute;tricos no es directa. En este caso, una llave de 1024 &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;bits&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; de RSA es equivalente en seguridad a una de 75 &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;bits&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; de un algoritmo sim&amp;eacute;trico. &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Como era de esperar, en nuestra demostraci&amp;oacute;n utilizaremos el algoritmo de mayor uso, RSA. Debido a que el funcionamiento es diferente comparado con el algoritmo anterior, la pantalla var&amp;iacute;a levemente. Existir&amp;aacute; una zona donde se desplegar&amp;aacute; la llave p&amp;uacute;blica generada, dej&amp;aacute;ndole el almacenamiento de la llave privada a la clase &lt;/span&gt;&lt;b&gt;&lt;span style="font-size:small;"&gt;miRSA&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:small;"&gt;. &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;La idea de esto es que exista una clase que provea una llave p&amp;uacute;blica, para que el cliente encripte la informaci&amp;oacute;n y luego &amp;eacute;ste le env&amp;iacute;e lo encriptado a la misma clase, para que con la llave privada la desencripte. En este caso, se ha dejado el m&amp;eacute;todo &lt;/span&gt;&lt;b&gt;&lt;span style="font-size:small;"&gt;desencriptar&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:small;"&gt; como p&amp;uacute;blico, por que se necesita para pintar el resultado en el formulario. Este no debiera ser un m&amp;eacute;todo p&amp;uacute;blico en una implementaci&amp;oacute;n real. &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Antes de ver la &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;demo&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;, es necesario revisar el siguiente cap&amp;iacute;tulo, debido a que la encriptaci&amp;oacute;n con RSA no es eficiente y tiene limitaciones de tama&amp;ntilde;o.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h4&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Encriptaci&amp;oacute;n Asim&amp;eacute;trica + Sim&amp;eacute;trica&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Debido a que la encriptaci&amp;oacute;n asim&amp;eacute;trica es casi 1000 veces m&amp;aacute;s lenta que la sim&amp;eacute;trica, cuando la informaci&amp;oacute;n a encriptar es mucha, se utiliza una combinaci&amp;oacute;n de algoritmos. El algoritmo sim&amp;eacute;trico se utiliza para encriptar la informaci&amp;oacute;n y el asim&amp;eacute;trico para encriptar la llave del algoritmo sim&amp;eacute;trico con que se encript&amp;oacute; la informaci&amp;oacute;n. Entonces, el proceso es mucho m&amp;aacute;s r&amp;aacute;pido. Esta t&amp;eacute;cnica se utiliza hoy en SSL en la negociaci&amp;oacute;n entre el navegador del cliente y el servidor. En cada ida y vuelta al servidor se generan nuevas llaves y se realiza todo el proceso. Tambi&amp;eacute;n es utilizada por &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Windows&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; en la encriptaci&amp;oacute;n de los archivos. &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Otro motivo para utilizar esta encriptaci&amp;oacute;n combinada es la necesidad de encriptar textos largos. La encriptaci&amp;oacute;n asim&amp;eacute;trica adem&amp;aacute;s de ser ineficiente en tiempo, tiene limitaciones de tama&amp;ntilde;o. El tama&amp;ntilde;o m&amp;aacute;ximo depende del largo de la llave. En la demostraci&amp;oacute;n, puedes probar colocando mucho texto y ver&amp;aacute;s que se cae. &lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Estas limitantes nos obligan a utilizar el m&amp;eacute;todo combinado. &lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Nuestra demostraci&amp;oacute;n implementa ambos m&amp;eacute;todos, y se decide cu&amp;aacute;l utilizar con la selecci&amp;oacute;n del &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;check&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; Utilizar Sim&amp;eacute;trico. La aplicaci&amp;oacute;n se ve como se muestra en la figura 4 y figura 5. Antes de hacer cada &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;demo&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;, se debe seleccionar si se utilizar&amp;aacute; en conjunto con encriptaci&amp;oacute;n sim&amp;eacute;trica.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p align="center"&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;&lt;img width="482" src="http://msmvps.com/blogs/pmackay/mtjnet/mtjnet-art218-img01-482x392.jpg" height="392" alt="" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:small;"&gt;Figura 4:&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:small;"&gt; Encriptaci&amp;oacute;n utilizando solamente RSA&lt;/span&gt;&lt;/span&gt;.&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;img width="482" src="http://msmvps.com/blogs/pmackay/mtjnet/mtjnet-art218-img02-482x392.jpg" height="392" alt="" /&gt;&lt;br /&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:small;"&gt;Figura 5:&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:small;"&gt; Encriptaci&amp;oacute;n utilizando RSA con &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Rijndael&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;.&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;El resultado de la encriptaci&amp;oacute;n es notoriamente m&amp;aacute;s largo. &lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Como vemos, si generamos una llave y luego procedemos con los siguientes pasos, la encriptaci&amp;oacute;n se produce en un lado y la desencriptaci&amp;oacute;n en otro. Incluso &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;.NET&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; provee el m&amp;eacute;todo &lt;/span&gt;&lt;b&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;ToXmlString()&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;span style="font-size:small;"&gt; de &lt;/span&gt;&lt;i&gt;&lt;b&gt;&lt;span style="font-size:small;"&gt;RSACryptoServiceProvider&lt;/span&gt;&lt;/b&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; que retorna la llave en formato XML, ideal para ser enviada por alg&amp;uacute;n medio p&amp;uacute;blico (&lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Web Service&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;, Archivo XML, etc.). &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Dependiendo de si se utiliza en conjunto con alg&amp;uacute;n algoritmo sim&amp;eacute;trico, la encriptaci&amp;oacute;n y desencriptaci&amp;oacute;n es diferente. Como algoritmo sim&amp;eacute;trico se utiliza AES &amp;oacute; &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Rijndael&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;. &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;El c&amp;oacute;digo de nuestra clase &lt;/span&gt;&lt;b&gt;&lt;span style="font-size:small;"&gt;miRSA&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:small;"&gt; es el siguiente:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table bgcolor="#d3d3d3" cellpadding="0" cellspacing="0"&gt;

&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;public class &lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="font-size:small;"&gt;miRSA&lt;br /&gt;&lt;/span&gt;{&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;private&lt;/span&gt;&lt;span style="font-size:small;"&gt; RSACryptoServiceProvider _objRSA = &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;null&lt;/span&gt;&lt;span style="font-size:small;"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;public&lt;/span&gt;&lt;span style="font-size:small;"&gt; miRSA()&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:small;"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:2;"&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;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;this&lt;/span&gt;&lt;span style="font-size:small;"&gt;._objRSA = &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;new&lt;/span&gt;&lt;span style="font-size:small;"&gt; RSACryptoServiceProvider(1024);&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:small;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="font-size:12pt;color:#0000ff;"&gt;string&lt;/span&gt;&lt;span style="font-size:small;"&gt; ObtenerLlavePublica()&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:small;"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:2;"&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;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="font-size:12pt;color:#0000ff;"&gt;this&lt;/span&gt;&lt;span style="font-size:small;"&gt;._objRSA.ToXmlString(&lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;false&lt;/span&gt;&lt;span style="font-size:small;"&gt;);&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:small;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="font-size:12pt;color:#0000ff;"&gt;string&lt;/span&gt;&lt;span style="font-size:small;"&gt; DesEncriptar(&lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;byte&lt;/span&gt;&lt;span style="font-size:small;"&gt;[] bytEncriptado, &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;bool&lt;/span&gt;&lt;span style="font-size:small;"&gt; blnConSimetrico)&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:small;"&gt;{ &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:2;"&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;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;if&lt;/span&gt;&lt;span style="font-size:small;"&gt; (blnConSimetrico)&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:2;"&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;/span&gt;&lt;span style="font-size:small;"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count: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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;byte&lt;/span&gt;&lt;span style="font-size:small;"&gt;[] keyArray = &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="font-size:12pt;color:#0000ff;"&gt;byte&lt;/span&gt;&lt;span style="font-size:small;"&gt;[_objRSA.KeySize/8];&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count: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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;byte&lt;/span&gt;&lt;span style="font-size:small;"&gt;[] encrypted = &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="font-size:12pt;color:#0000ff;"&gt;byte&lt;/span&gt;&lt;span style="font-size:small;"&gt;[bytEncriptado.Length - keyArray.Length];&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count: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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:small;"&gt;Array.Copy(bytEncriptado, 0, keyArray, 0, keyArray.Length);&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count: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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:small;"&gt;Array.Copy(bytEncriptado, keyArray.Length, encrypted, 0, encrypted.Length);&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count: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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;byte&lt;/span&gt;&lt;span style="font-size:small;"&gt;[] simKey = &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;this&lt;/span&gt;&lt;span style="font-size:small;"&gt;._objRSA.Decrypt(keyArray, &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;false&lt;/span&gt;&lt;span style="font-size:small;"&gt;);&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count: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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;return&lt;/span&gt;&lt;span style="font-size:small;"&gt; MiRijndael.Desencriptar(encrypted, simKey);&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:2;"&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;/span&gt;&lt;span style="font-size:small;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:2;"&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;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;else&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:2;"&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;/span&gt;&lt;span style="font-size:small;"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count: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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;return&lt;/span&gt;&lt;span style="font-size:small;"&gt; System.Text.Encoding.UTF8.GetString(&lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;this&lt;/span&gt;&lt;span style="font-size:small;"&gt;._objRSA.Decrypt(bytEncriptado, &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;false&lt;/span&gt;&lt;span style="font-size:small;"&gt;));&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:2;"&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;/span&gt;&lt;span style="FONT-SIZE:12pt;mso-fareast-language:ES-CL;mso-ansi-language:ES-CL;"&gt;}&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;span style="font-size:small;"&gt;&lt;br /&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;Y el c&amp;oacute;digo del cliente p&amp;uacute;blico es el siguiente (declarado en alg&amp;uacute;n lugar del formulario):&lt;/p&gt;
&lt;table bgcolor="#d3d3d3" cellpadding="0" cellspacing="0"&gt;

&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:12pt;color:#0000ff;mso-fareast-language:ES-CL;"&gt;private&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="font-size:small;"&gt; miRSA _objKey&lt;/span&gt;&lt;span style="FONT-SIZE:12pt;mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:small;"&gt;= &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;null&lt;/span&gt;&lt;span style="font-size:small;"&gt;; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;mso-fareast-language:ES-CL;"&gt;public&lt;/span&gt;&lt;span style="FONT-SIZE:12pt;mso-fareast-language:ES-CL;"&gt; Form1() &lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:12pt;mso-fareast-language:ES-CL;"&gt;{ &lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:small;"&gt;InitializeComponent(); &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;b style="mso-bidi-font-weight:normal;"&gt;&lt;span style="font-size:small;"&gt;_objKey = &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;new&lt;/span&gt;&lt;span style="font-size:small;"&gt; miRSA(); &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:12pt;mso-fareast-language:ES-CL;"&gt;} &lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;mso-fareast-language:ES-CL;"&gt;private&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt; &lt;span style="font-size:12pt;color:#0000ff;"&gt;void&lt;/span&gt;&lt;span style="font-size:small;"&gt; btnAsimEncriptar_Click(&lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;object&lt;/span&gt;&lt;span style="font-size:small;"&gt; sender, System.EventArgs e) &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:12pt;mso-fareast-language:ES-CL;mso-ansi-language:ES-CL;"&gt;{ &lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;mso-ansi-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;byte&lt;/span&gt;&lt;span style="font-size:small;"&gt;[] _bytEncriptado = &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;null&lt;/span&gt;&lt;span style="font-size:small;"&gt;; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;mso-ansi-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:12pt;color:#008000;"&gt;//Creamos una instancia del encritador publico &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;mso-ansi-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:small;"&gt;RSACryptoServiceProvider _objEncriptadorPublico = &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;new&lt;/span&gt;&lt;span style="font-size:small;"&gt; RSACryptoServiceProvider(); &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;mso-ansi-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:12pt;color:#008000;"&gt;//Le asignamos la llave genarada &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="font-size:small;"&gt;_objEncriptadorPublico.FromXmlString(&lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;this&lt;/span&gt;&lt;span style="font-size:small;"&gt;.txtAsimLlavePublica.Text); &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;mso-fareast-language:ES-CL;mso-ansi-language:ES-CL;"&gt;if&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;mso-ansi-language:ES-CL;"&gt;&lt;span style="font-size:small;"&gt; (&lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;this&lt;/span&gt;&lt;span style="font-size:small;"&gt;.chkSimetrica.Checked) &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;mso-ansi-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:small;"&gt;{ &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;mso-ansi-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:2;"&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;/span&gt;&lt;span style="font-size:12pt;color:#008000;"&gt;//Se declara la memoria para almacenar la llave utilizada por nuestro Rijndael personalizado &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:2;"&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;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;mso-fareast-language:ES-CL;"&gt;byte&lt;/span&gt;&lt;span style="FONT-SIZE:12pt;mso-fareast-language:ES-CL;"&gt;[] _bytKey = (Rijndael.Create()).Key; &lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:1;"&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;/span&gt;&lt;span style="font-size:12pt;color:#008000;mso-fareast-language:ES-CL;mso-ansi-language:ES-CL;"&gt;//Se encripta el texto y se obtiene la llave que se utiliz&amp;oacute; para la encriptaci&amp;oacute;n &lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;mso-ansi-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:2;"&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;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;byte&lt;/span&gt;&lt;span style="font-size:small;"&gt;[] _bytEncriptadoSimetrico = TransEncripHash.MiRijndael.Encriptar(&lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;this&lt;/span&gt;&lt;span style="font-size:small;"&gt;.txtAsimAEncriptar.Text, _bytKey); &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;mso-ansi-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:2;"&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;/span&gt;&lt;span style="font-size:12pt;color:#008000;"&gt;//Se encripta la llave con el algoritmo RSA &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:2;"&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;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;mso-fareast-language:ES-CL;"&gt;byte&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="font-size:small;"&gt;[] _bytEncriptadoLlave = _objEncriptadorPublico.Encrypt(_bytKey, &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;false&lt;/span&gt;&lt;span style="font-size:small;"&gt;); &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:2;"&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;/span&gt;&lt;span style="font-size:12pt;color:#008000;mso-fareast-language:ES-CL;mso-ansi-language:ES-CL;"&gt;//Se copia en un arreglo la llave encriptada y el encriptado de Rijndael &lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:2;"&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;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="font-size:small;"&gt;_bytEncriptado = &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="font-size:12pt;color:#0000ff;"&gt;byte&lt;/span&gt;&lt;span style="font-size:small;"&gt;[_bytEncriptadoLlave.Length + _bytEncriptadoSimetrico.Length]; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:2;"&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;/span&gt;&lt;span style="font-size:small;"&gt;_bytEncriptadoLlave.CopyTo(_bytEncriptado,0); &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:2;"&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;/span&gt;&lt;span style="font-size:small;"&gt;_bytEncriptadoSimetrico.CopyTo(_bytEncriptado, _bytEncriptadoLlave.Length); &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:small;"&gt;} &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;else &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:small;"&gt;{ &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:2;"&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;/span&gt;&lt;span style="font-size:small;"&gt;_bytEncriptado = _objEncriptadorPublico.Encrypt(System.Text.Encoding.UTF8.GetBytes(&lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;this&lt;/span&gt;&lt;span style="font-size:small;"&gt;.txtAsimAEncriptar.Text), &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;false&lt;/span&gt;&lt;span style="font-size:small;"&gt;); &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:small;"&gt;} &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;this&lt;/span&gt;&lt;span style="font-size:small;"&gt;.txtAsimEncriptado.Text = Convert.ToBase64String(_bytEncriptado); &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:12pt;mso-fareast-language:ES-CL;"&gt;} &lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;mso-fareast-language:ES-CL;"&gt;private&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt; &lt;span style="font-size:12pt;color:#0000ff;"&gt;void&lt;/span&gt;&lt;span style="font-size:small;"&gt; btnAsimDesEncriptar_Click(&lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;object&lt;/span&gt;&lt;span style="font-size:small;"&gt; sender, System.EventArgs e) &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:12pt;mso-fareast-language:ES-CL;"&gt;{ &lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;this&lt;/span&gt;&lt;span style="font-size:small;"&gt;.txtAsimDesEncriptado.Text = &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;this&lt;/span&gt;&lt;span style="font-size:small;"&gt;._objKey.DesEncriptar(Convert.FromBase64String(&lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;this&lt;/span&gt;&lt;span style="font-size:small;"&gt;.txtAsimEncriptado.Text), &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;this&lt;/span&gt;&lt;span style="font-size:small;"&gt;.chkSimetrica.Checked); &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:12pt;mso-fareast-language:ES-CL;"&gt;} &lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;mso-fareast-language:ES-CL;"&gt;private&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt; &lt;span style="font-size:12pt;color:#0000ff;"&gt;void&lt;/span&gt;&lt;span style="font-size:small;"&gt; btnAsimGenerar_Click(&lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;object&lt;/span&gt;&lt;span style="font-size:small;"&gt; sender, System.EventArgs e) &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:12pt;mso-fareast-language:ES-CL;"&gt;{ &lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;this&lt;/span&gt;&lt;span style="font-size:small;"&gt;.txtAsimLlavePublica.Text = &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;this&lt;/span&gt;&lt;span style="font-size:small;"&gt;._objKey.ObtenerLlavePublica(); &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:12pt;mso-fareast-language:ES-CL;mso-ansi-language:ES-CL;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;/table&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;En este ejemplo, la encriptaci&amp;oacute;n se produce en un lugar, luego de solicitar la clave p&amp;uacute;blica a la clase (pero que perfectamente puede ser un servicio &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Web&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;), la informaci&amp;oacute;n encriptada se puede enviar a este servicio &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Web&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; sin problemas de violaci&amp;oacute;n de seguridad, y sin necesidad de conocer ambas llaves. Si bien es cierto que la clase o servicio conoce ambas llaves, la llave p&amp;uacute;blica no le es de ninguna utilidad.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Antes de finalizar con este algoritmo, cabe mencionar que donde puede haber problemas es en la generaci&amp;oacute;n de la llave. Por eso, &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Diffie-Hellman&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; (&amp;amp; &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Merkle&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;) se especializa en mejorar ese proceso, ya que es de vital importancia la generaci&amp;oacute;n de llaves.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p class="txt-msdn-notas"&gt;&lt;span style="font-family:Calibri;"&gt;&lt;b&gt;&lt;span style="font-size:small;"&gt;Nota:&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:small;"&gt; Existe cierta codificaci&amp;oacute;n que puede haber pasado desapercibida hasta ahora. Esta es la utilizaci&amp;oacute;n de distintos m&amp;eacute;todos para transformar textos en arreglos de &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;bytes&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;, y viceversa. Los m&amp;eacute;todos reales para hacerlo son los que est&amp;aacute;n implementados en los &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;encodings&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; de &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;.NET&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;, como por ejemplo &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;System.Text.Encoding.UTF8.GetString(bytes)&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; y &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;System.Text.Encoding.UTF8.GetBytes(string)&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;. En las &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;demos&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; se ha cambiado algunos deliberadamente por &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Convert.ToBase64String(bytes)&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; y &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Convert.FromBase64String(string)&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; para poder desplegarlo en los controles del formulario &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Windows&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;. El resultado de una encriptaci&amp;oacute;n genera car&amp;aacute;cteres visibles y no visibles. Si no se transforman a &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Base64&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; y desde &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Base64&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; mientras son almacenados en un control, se pierde informaci&amp;oacute;n. Si el resultado de la encriptaci&amp;oacute;n no va a ser desplegado sino que ser&amp;aacute; almacenado en alg&amp;uacute;n medio, los &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;bytes&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; de &amp;eacute;ste pueden escribirse sin problemas en el medio que sea.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;&lt;span style="font-family:Calibri;"&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Hash&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Por &amp;uacute;ltimo, nos quedan los algoritmos de tipo &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Hash&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;. Estos son algoritmos del tipo de los que se conocen como de s&amp;oacute;lo ida, ya que no es posible desencriptar lo que se ha encriptado. Puede ser que a primera vista no se le vea la utilidad, pero en los siguientes dos escenarios &amp;eacute;ste es el tipo de algoritmo necesario para realizar el proceso. El primero de ellos est&amp;aacute; dirigido a proteger informaci&amp;oacute;n muy valiosa encriptando el contenido; y el segundo busca validar que no se modifique la informaci&amp;oacute;n que se est&amp;aacute; enviando desde un lugar a otro.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="font-family:Calibri;"&gt;&lt;b&gt;&lt;span style="font-size:small;"&gt;Escenario 1:&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:small;"&gt; Almacenar contrase&amp;ntilde;as de un sistema. Las contrase&amp;ntilde;as de cualquier sistema serio jam&amp;aacute;s debieran poder desencriptarse. El motivo es simple. Si se pueden desencriptar, el riesgo de que alguien conozca la llave y tenga acceso a todo el sistema con todos los usuarios es muy grande. Entonces, si no puedo desencriptar una contrase&amp;ntilde;a, &amp;iquest;C&amp;oacute;mo puedo saber entonces si una contrase&amp;ntilde;a entregada es v&amp;aacute;lida? La respuesta es muy simple. Se encripta la contrase&amp;ntilde;a entregada y se compara el resultado de la encriptaci&amp;oacute;n con la contrase&amp;ntilde;a previamente almacenada. &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-family:Calibri;"&gt;&lt;b&gt;&lt;span style="font-size:small;"&gt;Escenario 2:&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:small;"&gt; Validar que cierta informaci&amp;oacute;n no se haya modificado. Si se desea enviar un bloque de datos y se quiere estar seguro de que nadie lo ha modificado durante el camino, lo que se hace es enviar el bloque de informaci&amp;oacute;n sin encriptar y adem&amp;aacute;s se env&amp;iacute;a un &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Hash/Digest&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; de este mismo bloque de datos. Entonces, nuestro receptor al tener la informaci&amp;oacute;n sin encriptar, le aplica un &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Hash&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; y con el mismo criterio del Escenario 1, determina si ambos bloques son iguales. Si lo son, el bloque que no est&amp;aacute; con &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Hash&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; es el original. &amp;iquest;Porqu&amp;eacute; no usar un algoritmo de encriptaci&amp;oacute;n reversible? Porque &amp;eacute;ste podr&amp;iacute;a ser desencriptado, modificado y vuelto a encriptar y el receptor jam&amp;aacute;s sabr&amp;iacute;a que fue modificado en el camino. Como el &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Hash&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; no es reversible, esto &amp;uacute;ltimo no podr&amp;aacute; suceder jam&amp;aacute;s. &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Los algoritmos para hacer &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Hash&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; mas conocidos son los siguientes:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table align="center" cellpadding="0" cellspacing="0"&gt;

&lt;tr&gt;
&lt;td&gt;
&lt;table cellpadding="5" cellspacing="0"&gt;

&lt;tr align="left"&gt;
&lt;td&gt;
&lt;div align="center" style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;b&gt;&lt;span style="color:#ffffff;"&gt;Algoritmo&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;div align="center"&gt;&lt;b&gt;&lt;span style="color:#ffffff;"&gt;&lt;span&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Tama&amp;ntilde;o del &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Hash&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; (&lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;bits)&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr align="left"&gt;
&lt;td style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;MD5&lt;/td&gt;
&lt;td&gt;
&lt;div align="right" style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;128&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr align="left"&gt;
&lt;td style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;SHA-1&lt;/td&gt;
&lt;td&gt;
&lt;div align="right" style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;160&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr align="left"&gt;
&lt;td style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;SHA-256&lt;/td&gt;
&lt;td&gt;
&lt;div align="right" style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;256&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr align="left"&gt;
&lt;td style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;SHA-384&lt;/td&gt;
&lt;td&gt;
&lt;div align="right" style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;384&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr align="left"&gt;
&lt;td style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;SHA-512&lt;/td&gt;
&lt;td&gt;
&lt;div align="right" style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;512&lt;/div&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;span style="font-size:small;"&gt;La robustez de un algoritmo de &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Hash&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; es comparable a la mitad del largo del resultado en &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;bits&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;. Entonces, pensar que con MD5 se est&amp;aacute; seguro puede ser un error. SHA-256 es el indicado para obtener seguridad de 128 &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;bits&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;. Es un hecho que SHA-256 es mucho m&amp;aacute;s lento, pero como &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Bruce Schneier&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; dice &amp;ldquo;Ya existen suficientes sistemas r&amp;aacute;pidos e inseguros&amp;rdquo;. &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Pero a pesar de parecer muy efectivo, existe un problema con el &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Hash&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; para cada uno de los escenarios indicados anteriormente. Como son problemas conocidos, existen soluciones conocidas tambi&amp;eacute;n. Revisemos ahora cada uno de los problemas y sus soluciones. &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;b&gt;&lt;span style="font-size:small;"&gt;Problemas Escenario 1&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;Si bien el problema no est&amp;aacute; tan relacionado con el &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Hash&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;, debido a la utilizaci&amp;oacute;n de contrase&amp;ntilde;as de escasa dificultad, haciendo un ataque de fuerza bruta o por diccionario se podr&amp;iacute;an encontrar valores de &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Hash&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; que coinciden con el &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Hash&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; de las contrase&amp;ntilde;as almacenadas. Para esto se pueden ejecutar dos planes de acci&amp;oacute;n independientes, pero obteni&amp;eacute;ndose el mejor resultado con la utilizaci&amp;oacute;n de ambos. &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;La &lt;/span&gt;&lt;b&gt;&lt;span style="font-size:small;"&gt;Soluci&amp;oacute;n 1&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:small;"&gt; consiste en realizar varias pasadas de &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Hash&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; sobre los datos, aplic&amp;aacute;ndole el &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Hash&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; al resultado del &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Hash&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; anterior. Realizando esto varios cientos de veces (idealmente mil veces) podemos dificultar m&amp;aacute;s el trabajo de un &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;hacker&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;. M&amp;aacute;s informaci&amp;oacute;n de porqu&amp;eacute; se debe iterar muchas veces y las consecuencias de no hacerlo, la puedes encontrar en &lt;/span&gt;&lt;a href="http://www.atrevido.net/blog/PermaLink.aspx?guid=12b1338b-171e-4692-850e-8f59ed12f24a"&gt;&lt;span style="font-size:small;"&gt;http://www.atrevido.net/blog/PermaLink.aspx?guid=12b1338b-171e-4692-850e-8f59ed12f24a&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:small;"&gt; . &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;La &lt;/span&gt;&lt;b&gt;&lt;span style="font-size:small;"&gt;Soluci&amp;oacute;n 2&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:small;"&gt; requiere agregar un texto adicional a la contrase&amp;ntilde;a. Esto se conoce como &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Salt&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;. Entonces, cada vez que un usuario cambie o est&amp;eacute; validando una contrase&amp;ntilde;a, hay que concatenarle a la contrase&amp;ntilde;a este &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Salt&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; y de ah&amp;iacute; generar el &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Hash&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;. De esta forma le agrega variaci&amp;oacute;n a las contrase&amp;ntilde;as pobremente definidas. Esta soluci&amp;oacute;n requiere un trabajo adicional ya que es necesario adem&amp;aacute;s almacenar el texto del &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Salt&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; junto a la informaci&amp;oacute;n del usuario y la contrase&amp;ntilde;a encriptada. Este texto se debe crear con car&amp;aacute;cteres generados al azar. &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;En el ejemplo se mostrar&amp;aacute; la combinaci&amp;oacute;n de ambas soluciones. Como encriptaci&amp;oacute;n de &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Hash&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; se usar&amp;aacute; SHA256. Los otros algoritmos mencionados con anterioridad est&amp;aacute;n disponibles tambi&amp;eacute;n en &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;.NET&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;. &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;El resultado de la encriptaci&amp;oacute;n 1000 veces de cierto texto con un &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Salt&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; definido, es el que se muestra en la figura 6: &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p align="center"&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;&lt;img width="482" src="http://msmvps.com/blogs/pmackay/mtjnet/mtjnet-art218-img03-482x392.jpg" height="392" alt="" /&gt;&lt;br /&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:small;"&gt;Figura 6&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:small;"&gt;. &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;El c&amp;oacute;digo para realizar esto es muy simple y es el que se muestra a continuaci&amp;oacute;n:&lt;/p&gt;
&lt;table bgcolor="#d3d3d3" cellpadding="0" cellspacing="0"&gt;

&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:12pt;color:#0000ff;mso-fareast-language:ES-CL;"&gt;public&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt; &lt;span style="font-size:12pt;color:#0000ff;"&gt;class&lt;/span&gt;&lt;span style="font-size:small;"&gt; HashContrase&amp;ntilde;as&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:12pt;mso-fareast-language:ES-CL;"&gt;{&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="font-size:12pt;color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="font-size:12pt;color:#0000ff;"&gt;byte&lt;/span&gt;&lt;span style="font-size:small;"&gt;[] Encriptar(&lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;string&lt;/span&gt;&lt;span style="font-size:small;"&gt; strPassword, &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;string&lt;/span&gt;&lt;span style="font-size:small;"&gt; strSalt, &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;int&lt;/span&gt;&lt;span style="font-size:small;"&gt; intIteraciones)&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:small;"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:2;"&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span style="font-size:12pt;color:#0000ff;font-family:Calibri;mso-fareast-language:ES-CL;mso-bidi-font-size:8.0pt;"&gt;string&lt;/span&gt;&lt;span style="font-size:12pt;font-family:Calibri;mso-fareast-language:ES-CL;mso-bidi-font-size:8.0pt;"&gt; _strPasswordSalt = strPassword + strSalt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:12pt;font-family:Calibri;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span style="mso-fareast-language:ES-CL;mso-bidi-font-size:8.0pt;"&gt;&lt;span style="font-size:12pt;font-family:Calibri;mso-tab-count:2;"&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;SHA256Managed _objSha256 = &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;new&lt;/span&gt;&lt;span style="font-size:small;"&gt; SHA256Managed();&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:12pt;font-family:Calibri;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;mso-bidi-font-size:8.0pt;"&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:2;"&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;byte&lt;/span&gt;&lt;span style="font-size:small;"&gt;[] _objTemporal = &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;null&lt;/span&gt;&lt;span style="font-size:small;"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Calibri;mso-fareast-language:ES-CL;mso-bidi-font-size:8.0pt;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:2;"&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;try&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:12pt;font-family:Calibri;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;mso-bidi-font-size:8.0pt;"&gt;&lt;span style="font-size:12pt;font-family:Calibri;mso-tab-count:2;"&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:12pt;font-family:Calibri;"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:12pt;font-family:Calibri;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;mso-bidi-font-size:8.0pt;"&gt;&lt;span style="font-size:12pt;font-family:Calibri;mso-tab-count: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;&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;&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;/span&gt;&lt;span style="font-size:12pt;font-family:Calibri;"&gt;_objTemporal = System.Text.Encoding.UTF8.GetBytes(_strPasswordSalt);&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:12pt;font-family:Calibri;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;mso-bidi-font-size:8.0pt;"&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count: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;&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;&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;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;for&lt;/span&gt;&lt;span style="font-size:small;"&gt; (&lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;int&lt;/span&gt;&lt;span style="font-size:small;"&gt; i = 0; i &amp;lt;= intIteraciones - 1; i++)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:4;"&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;&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;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:12pt;font-family:Calibri;mso-fareast-language:ES-CL;mso-ansi-language:ES-CL;mso-bidi-font-size:8.0pt;"&gt;_objTemporal = _objSha256.ComputeHash(_objTemporal);&lt;/span&gt;&lt;span style="font-size:12pt;font-family:Calibri;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;mso-ansi-language:ES-CL;mso-bidi-font-size:8.0pt;"&gt;&lt;span style="font-size:12pt;font-family:Calibri;mso-tab-count:2;"&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:12pt;font-family:Calibri;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:12pt;font-family:Calibri;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;mso-ansi-language:ES-CL;mso-bidi-font-size:8.0pt;"&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:2;"&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;finally&lt;/span&gt;&lt;span style="font-size:small;"&gt; { _objSha256.Clear(); }&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;mso-ansi-language:ES-CL;mso-bidi-font-size:8.0pt;"&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:2;"&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;return&lt;/span&gt;&lt;span style="font-size:small;"&gt; _objTemporal;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="FONT-SIZE:12pt;mso-fareast-language:ES-CL;mso-ansi-language:ES-CL;"&gt;}&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:12pt;mso-fareast-language:ES-CL;mso-ansi-language:ES-CL;"&gt;} &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;/table&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;b&gt;&lt;span style="font-size:small;"&gt;Qu&amp;eacute; cosas se deben clarificar en este proceso&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;El resultado de este &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Hash&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; (Sha256) siempre retorna 256 &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;bits&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;, es decir, 32 &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;bytes&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;. Cuidado con confundir con el largo del &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;string&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; resultante de la conversi&amp;oacute;n a &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Base&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;64. Esta conversi&amp;oacute;n genera m&amp;aacute;s car&amp;aacute;cteres. Para verificar, puedes medir el largo del arreglo colocando un punto de interrupci&amp;oacute;n en el retorno (&lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;return&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;), y notar&amp;aacute;s que son 32 &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;bytes&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Adem&amp;aacute;s, las funciones de &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;hash&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; no tienen limitante para el tama&amp;ntilde;o del texto de entrada. Sea cual fuere el tama&amp;ntilde;o, el largo de la salida es el mismo y se procesan todos los car&amp;aacute;cteres del &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;string&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; de entrada.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Para un sistema de almacenamiento de contrase&amp;ntilde;as de usuario seguro, hay que hacer algunas modificaciones a esta funci&amp;oacute;n, pero son m&amp;iacute;nimas. Las modificaciones no pasan por cambios en el algoritmo, sino m&amp;aacute;s bien por crear una funci&amp;oacute;n para que genere &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Salt&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; rand&amp;oacute;micos y crear la funci&amp;oacute;n para la comparaci&amp;oacute;n de las contrase&amp;ntilde;as.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Probablemente te preguntes porqu&amp;eacute; hay 2 cajas de texto con el mismo texto. Como este proceso es com&amp;uacute;n, o al menos debiera serlo, &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;.NET&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; provee una clase llamada &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;PasswordDeriveBytes&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; que sirve para realizar de forma autom&amp;aacute;tica todo lo anteriormente visto. En el evento &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;click&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;, adem&amp;aacute;s de la llamada a la funci&amp;oacute;n detallada de m&amp;aacute;s arriba (&lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;HashContrase&amp;ntilde;as.Encriptar&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;), se crea una instancia de esta clase (&lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;PasswordDeriveBytes&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;) y se le especifican los mismos par&amp;aacute;metros que estamos utilizando en nuestro algoritmo de &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Hash&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; (la contrase&amp;ntilde;a, el &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Salt&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;, el algoritmo SHA256 y la cantidad de iteraciones). Esto hace que en s&amp;oacute;lo pocas l&amp;iacute;neas se pueda realizar el mismo proceso.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;El c&amp;oacute;digo ejecutado es el siguiente:&lt;/p&gt;
&lt;table bgcolor="#d3d3d3" cellpadding="0" cellspacing="0"&gt;

&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;PasswordDeriveBytes _objPdb = &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;new&lt;/span&gt;&lt;span style="font-size:small;"&gt; PasswordDeriveBytes(&lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;this&lt;/span&gt;&lt;span style="font-size:small;"&gt;.txtHashEncriptar1.Text, System.Text.Encoding.UTF8.GetBytes(&lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;this&lt;/span&gt;&lt;span style="font-size:small;"&gt;.txtSalt.Text), &amp;quot;SHA256&amp;quot;, Convert.ToInt32(&lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;this&lt;/span&gt;&lt;span style="font-size:small;"&gt;.txtCantidad.Text));&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;this&lt;/span&gt;&lt;span style="font-size:small;"&gt;.txtHashEncriptado2.Text = Convert.ToBase64String(_objPdb.GetBytes(32));&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;/table&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Para comparar arreglos de &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;bytes&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;, se ver&amp;aacute; m&amp;aacute;s adelante una funci&amp;oacute;n con tal objetivo.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;b&gt;&lt;span style="font-size:small;"&gt;Problemas Escenario 2:&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:small;"&gt; Si alguien puede ejecutar un &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Hash&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; sobre un conjunto de datos y obtener el resultado, &amp;iquest;Porqu&amp;eacute; no podr&amp;iacute;a modificar el contenido del documento que estamos enviando y generar el &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Hash&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; nuevamente, reemplazando el contenido del &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Hash&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; anterior? &amp;iquest;C&amp;oacute;mo se puede diferenciar mi proceso de &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Hash&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; del proceso de &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Hash&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; impostor? No es posible a menos que haya alguna llave de por medio.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Debido a lo anterior, se han inventado los siguientes algoritmos de &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Hash&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;, que utilizan llaves para realizar el proceso. En este caso, si el resultado se sobrescribe, al obtener el &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Hash&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; con la llave, el resultado jam&amp;aacute;s coincidir&amp;aacute; con el que viene en el mensaje.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Estos algoritmos y sus llaves son los siguientes:&lt;/p&gt;
&lt;table align="center" cellpadding="0" cellspacing="0"&gt;

&lt;tr&gt;
&lt;td&gt;
&lt;table cellpadding="5" cellspacing="0"&gt;

&lt;tr align="left"&gt;
&lt;td&gt;
&lt;div align="center" style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;b&gt;&lt;span style="color:#ffffff;"&gt;Algoritmo&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;div align="center"&gt;&lt;b&gt;&lt;span style="color:#ffffff;"&gt;&lt;span&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Tama&amp;ntilde;o del &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Hash&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; (&lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;bits)&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;div align="center"&gt;&lt;b&gt;&lt;span style="color:#ffffff;"&gt;&lt;span&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Tama&amp;ntilde;o de llave (&lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;bits)&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr align="left"&gt;
&lt;td style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;HMAC-SHA1&lt;/td&gt;
&lt;td style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;160&lt;/td&gt;
&lt;td&gt;
&lt;div align="right" style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;64&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr align="left"&gt;
&lt;td style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;MAC-3DES-CBC&lt;/td&gt;
&lt;td style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;64&lt;/td&gt;
&lt;td&gt;
&lt;div align="right" style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;8, 16, 24&lt;/div&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;span style="font-size:small;"&gt;Para realizar la &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;demo&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;, debemos primero generar una llave. Hasta ahora, las llaves se han creado manualmente, pero ahora vamos a utilizar herramientas del &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Framework&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; para generarlas. Como la llave de 64 &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;bits&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; es del mismo largo que la que utiliza el algoritmo DES, se utilizar&amp;aacute; la clase de &amp;eacute;ste para generar una. Existe el bot&amp;oacute;n &amp;ldquo;Generar Key&amp;rdquo; que es el encargado de generar y almacenar una llave. Esta se genera en la funci&amp;oacute;n del bot&amp;oacute;n, y se almacena en una variable de formulario. El c&amp;oacute;digo es el siguiente:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table bgcolor="#d3d3d3" cellpadding="0" cellspacing="0"&gt;

&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&lt;span style="font-size:12pt;color:#0000ff;font-family:Calibri;"&gt;privatevoid&lt;/span&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt; btnHashKey_Click(&lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;object&lt;/span&gt;&lt;span style="font-size:small;"&gt; sender, System.EventArgs e)&lt;br /&gt;&lt;/span&gt;{&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;this&lt;/span&gt;&lt;span style="font-size:small;"&gt;._objHashKey = (&lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;new&lt;/span&gt;&lt;span style="font-size:small;"&gt; System.Security.Cryptography.DESCryptoServiceProvider()).Key;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;this&lt;/span&gt;&lt;span style="font-size:small;"&gt;.lblSalt.Text = &amp;quot;Key : &amp;quot; + Convert.ToBase64String(&lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;this&lt;/span&gt;&lt;span style="font-size:small;"&gt;._objHashKey);&lt;br /&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;/table&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Con la primer sentencia se crea la instancia del proveedor de DES y se obtiene el &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Key&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; almacen&amp;aacute;ndolo en &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;_objHashKey&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;, una variable de formulario. Con la segunda l&amp;iacute;nea, se copia el contenido de la &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Key&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; en una etiqueta del formulario, previamente transform&amp;aacute;ndolo en &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Base&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;64. Cabe mencionar que la transformaci&amp;oacute;n a &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Base&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;64 genera una cadena m&amp;aacute;s larga que la cantidad de &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;bytes&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; que est&amp;aacute; recibiendo, por eso si cuentas la cantidad de car&amp;aacute;cteres del &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Key&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;, no cumple con ser de 64 &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;bits&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; (8 &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;bytes&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;). &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;La validaci&amp;oacute;n es muy simple de realizar. Recuerda que lo que se quiere hacer es verificar que la informaci&amp;oacute;n que se est&amp;aacute; enviando no se haya modificado en el camino. Entonces lo que se debe hacer es generar un nuevo &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Hash&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; con el texto en cuesti&amp;oacute;n y la contrase&amp;ntilde;a, y comparar el resultado del &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Hash&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; generado con el que se envi&amp;oacute; inicialmente. La comparaci&amp;oacute;n de &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Hash&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; se realiza con una funci&amp;oacute;n para comparar arreglos (Ver figura 7): &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p align="center"&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;&lt;img width="482" src="http://msmvps.com/blogs/pmackay/mtjnet/mtjnet-art218-img04-482x392.jpg" height="392" alt="" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:small;"&gt;Figura 7&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:small;"&gt;: Resultado de presionar &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Validar &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Hash&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt; sin hacer ninguna modificaci&amp;oacute;n.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;En cambio, si se modifica levemente el texto, agregando la palabra &amp;quot;me&amp;quot; (o cualquiera) en el c&amp;iacute;rculo rojo remarcado, y se trata de validar, el resultado es err&amp;oacute;neo inmediatamente. Con esta funcionalidad se valida que nadie haya modificado el contenido de lo que se est&amp;aacute; enviando (Ver figura 8): &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p align="center"&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;&lt;img width="482" src="http://msmvps.com/blogs/pmackay/mtjnet/mtjnet-art218-img05-482x392.jpg" height="392" alt="" /&gt;&lt;br /&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:small;"&gt;Figura 8: &lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:small;"&gt;Resultado de presionar &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Validar &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Hash&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt; con una modificaci&amp;oacute;n&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Adem&amp;aacute;s, si se genera una nueva &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Key&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; (con el bot&amp;oacute;n &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Generar &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Key&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;) y se valida, el resultado es fallido, como era de esperarse. Existe otro m&amp;eacute;todo para realizar esta misma validaci&amp;oacute;n pero sin compartir las llaves. La idea es muy similar a la estudiada en los algoritmos asim&amp;eacute;tricos, en donde una de las partes tiene una llave para encriptar y otra parte tiene otra llave para encriptar tambi&amp;eacute;n. Algo similar a esto es lo que se utiliza para la firma digital, pero por ser un tema tan amplio, no cabe en este art&amp;iacute;culo y merece un art&amp;iacute;culo completo para su explicaci&amp;oacute;n. Algunas claves para poder conocer como funciona esto, las siguientes clases del &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Framework&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; poseen funcionalidad para lograrlo. Estas son &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;RSACryptoServiceProvider&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; y &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;DSACryptoServiceProvider&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;. Por &amp;uacute;ltimo, algo de c&amp;oacute;digo. Para generar un&lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt; Hash&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; con un &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Key&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; y para comparar arreglos de &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;bytes&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; se utilizan los siguientes bloques de c&amp;oacute;digo:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table bgcolor="#d3d3d3" cellpadding="0" cellspacing="0"&gt;

&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:12pt;color:#0000ff;mso-fareast-language:ES-CL;"&gt;public&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt; &lt;span style="font-size:12pt;color:#0000ff;"&gt;class&lt;/span&gt;&lt;span style="font-size:small;"&gt; HashValidacion &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:12pt;mso-fareast-language:ES-CL;"&gt;{ &lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="font-size:12pt;color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="font-size:12pt;color:#0000ff;"&gt;byte&lt;/span&gt;&lt;span style="font-size:small;"&gt;[] Encriptar(&lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;string&lt;/span&gt;&lt;span style="font-size:small;"&gt; strTexto, &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;byte&lt;/span&gt;&lt;span style="font-size:small;"&gt;[] objKey) &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:small;"&gt;{ &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:2;"&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;/span&gt;&lt;span style="font-size:small;"&gt;HMACSHA1 _objHMACSHA = &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;new&lt;/span&gt;&lt;span style="font-size:small;"&gt; HMACSHA1(objKey); &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:2;"&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;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;try &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:2;"&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;/span&gt;&lt;span style="font-size:small;"&gt;{ &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count: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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;return&lt;/span&gt;&lt;span style="font-size:small;"&gt; _objHMACSHA.ComputeHash(Encoding.UTF8.GetBytes(strTexto)); &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:2;"&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;/span&gt;&lt;span style="font-size:small;"&gt;} &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:2;"&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;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;finally &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:2;"&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;/span&gt;&lt;span style="font-size:small;"&gt;{ &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count: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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:small;"&gt;_objHMACSHA.Clear(); &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:2;"&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;/span&gt;&lt;span style="font-size:small;"&gt;} &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:small;"&gt;} &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="font-size:12pt;color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="font-size:12pt;color:#0000ff;"&gt;bool&lt;/span&gt;&lt;span style="font-size:small;"&gt; CompareByteArray(Byte[] arrayA, Byte[] arrayB) &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:small;"&gt;{ &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:2;"&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;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;if&lt;/span&gt;&lt;span style="font-size:small;"&gt; (arrayA.Length != arrayB.Length) &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count: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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="font-size:12pt;color:#0000ff;"&gt;false&lt;/span&gt;&lt;span style="font-size:small;"&gt;; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:2;"&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;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;for&lt;/span&gt;&lt;span style="font-size:small;"&gt; (&lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;int&lt;/span&gt;&lt;span style="font-size:small;"&gt; i = 0; i &amp;lt;= arrayA.Length - 1; i++) &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count: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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;if&lt;/span&gt;&lt;span style="font-size:small;"&gt; (!arrayA.Equals(arrayB)) &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:4;"&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;mso-fareast-language:ES-CL;mso-ansi-language:ES-CL;"&gt;return&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;mso-ansi-language:ES-CL;"&gt; &lt;span style="font-size:12pt;color:#0000ff;"&gt;false&lt;/span&gt;&lt;span style="font-size:small;"&gt;; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;mso-ansi-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:2;"&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;/span&gt;&lt;span style="font-size:12pt;color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="font-size:12pt;color:#0000ff;"&gt;true&lt;/span&gt;&lt;span style="font-size:small;"&gt;; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-fareast-language:ES-CL;mso-ansi-language:ES-CL;"&gt;&lt;span style="FONT-SIZE:12pt;mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size:small;"&gt;} &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:12pt;mso-fareast-language:ES-CL;mso-ansi-language:ES-CL;"&gt;} &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;/table&gt;
&lt;h4&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Conclusiones&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;A trav&amp;eacute;s de las dos partes de este art&amp;iacute;culo se han explorado los m&amp;eacute;todos m&amp;aacute;s comunes de encriptaci&amp;oacute;n, revis&amp;aacute;ndose cada escenario donde se aplican. Cada escenario se ha complementado con ejemplos y c&amp;oacute;digo 100% funcional. Se ha&amp;nbsp; desmitificado la encriptaci&amp;oacute;n como un proceso complicado y nebuloso, mostr&amp;aacute;ndose de forma clara cu&amp;aacute;ndo y c&amp;oacute;mo aplicar cada algoritmo, adem&amp;aacute;s de la forma correcta de hacerlo.&lt;/p&gt;
&lt;h4&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Respuestas a las Preguntas&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span style="font-size:12pt;font-family:Calibri;"&gt;Revisemos entonces algunas de las preguntas inicialmente planteadas y veamos c&amp;oacute;mo podemos responderlas ahora. &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;&amp;iquest;Se est&amp;aacute; almacenando la informaci&amp;oacute;n cr&amp;iacute;tica de forma segura?&lt;br /&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:small;"&gt;Esta pregunta la puede respnder el lector.&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;&amp;iquest;Qu&amp;eacute; entendemos por seguro?&lt;br /&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:small;"&gt;Se ha mostrado la diferencia entre algoritmos que transforman texto con respecto a otros que realmente encriptan. &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Si se est&amp;aacute; encriptando, &amp;iquest;Qu&amp;eacute; algoritmo se est&amp;aacute; utilizando?&lt;br /&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:small;"&gt;Se revisaron los algoritmos m&amp;aacute;s conocidos y se mostraron sus ventajas y falencias. Sea cual fuere, el algoritmo debe implementarse adecuadamente.&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;&amp;iquest;Se permite la desencriptaci&amp;oacute;n de datos que no debieran poder desencriptarse?&lt;br /&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:small;"&gt;Esta pregunta la puede responder el lector, pero la respuesta debe ser NO. &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;&amp;iquest;C&amp;oacute;mo est&amp;aacute; realiz&amp;aacute;ndose la encriptaci&amp;oacute;n?&lt;br /&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:small;"&gt;Se revis&amp;oacute; la forma correcta de encriptar con cada algoritmo, como tambi&amp;eacute;n las malas pr&amp;aacute;cticas y los riesgos que se corren al no hacer el proceso como debe ser.&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;&amp;iquest;D&amp;oacute;nde est&amp;aacute;n almacenadas la o las llaves?&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Esta es una muy buena pregunta y la respuesta escapa al alcance de este art&amp;iacute;culo, pero como sugerencia se puede mencionar lo siguiente: se puede utilizar &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;DPAPI&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; o &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Certificate Storage&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;. Para implementar DPAPI tanto desde aplicaciones &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Windows&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; como &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;web&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;, puedes visitar los siguientes enlaces:&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;&lt;br /&gt;DPAPI: &lt;/span&gt;&lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetsec/html/SecNetHT07.asp"&gt;&lt;span style="font-size:small;"&gt;http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetsec/html/SecNetHT07.asp&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:small;"&gt;&lt;br /&gt;DPAPI en &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;Web&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;: &lt;/span&gt;&lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetsec/html/SecNetHT09.asp"&gt;&lt;span style="font-size:small;"&gt;http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetsec/html/SecNetHT09.asp&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;
&lt;p&gt;&lt;b&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Pensamientos como el siguiente no son seguros: &amp;quot;si almaceno la llave en un directorio escondido, es dif&amp;iacute;cil que un &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;hacker&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; la encuentre&amp;quot;, como as&amp;iacute; tambi&amp;eacute;n &amp;quot;A un &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;hacker &lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt;le va a tomar mucho tiempo encontrarla.&amp;quot; Si hay algo que le sobra a un &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;hacker&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; es tiempo y ganas.&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;&amp;iquest;Con qu&amp;eacute; frecuencia se cambian las llaves?&lt;br /&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:small;"&gt;La respuesta es depende, lamentablemente. Depende de la criticidad del sistema, como tambi&amp;eacute;n del uso de las llaves. Para una conexi&amp;oacute;n de transferencia, se crean las llaves, se utilizan y se descartan. En un sistema cr&amp;iacute;tico tal como el de un banco, el cambio de llaves deber&amp;iacute;a hacerse cada una hora, o como m&amp;aacute;ximo, cada un d&amp;iacute;a. Para informaci&amp;oacute;n que va a tener mayor duraci&amp;oacute;n, el tiempo puede ser mayor.&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;&amp;iquest;C&amp;oacute;mo enfrento el problema de cambiar las llaves con tanta frecuencia?&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Como cambiar las llaves no es una tarea simple en recursos y tiempo, se emplea el concepto de llave maestra y llaves hijas. La informaci&amp;oacute;n a encriptar se encripta con las llaves hijas y luego&amp;nbsp; con la llave maestra se encriptan las llaves hijas y se almacenan.&amp;nbsp; Entonces, al momento de aplicar cambio de llave, se cambia s&amp;oacute;lo la llave maestra, procedi&amp;eacute;ndose a desencriptar todas las llaves hijas con la antigua y a encriptar todas con la llave nueva. Esto disminuye el tiempo a factor de N (cantidad de llaves) y no de la cantidad de &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;bytes&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; de informaci&amp;oacute;n encriptada. Esto no agrega seguridad, s&amp;oacute;lo ayuda a realizar un proceso de forma eficiente.&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:12pt;font-family:Calibri;"&gt; &lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;&amp;iquest;Con qu&amp;eacute; criterio se definen las nuevas llaves?&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Para definir una llave se puede ejecutar la funci&amp;oacute;n &lt;/span&gt;&lt;i&gt;&lt;span style="font-size:small;"&gt;GenerateKey()&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:small;"&gt; que todo algoritmo sim&amp;eacute;trico posee. Esto genera una llave rand&amp;oacute;mica.&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size:12pt;font-family:Calibri;"&gt; &lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1436186" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/pmackay/archive/tags/Seguridad/default.aspx">Seguridad</category></item><item><title>Contadores de rendimiento de aplicaciones de 32 bits en sistemas de 64 bits</title><link>http://msmvps.com/blogs/pmackay/archive/2007/11/13/post26.aspx</link><pubDate>Tue, 13 Nov 2007 23:03:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1307811</guid><dc:creator>pmackay</dc:creator><slash:comments>0</slash:comments><comments>http://msmvps.com/blogs/pmackay/archive/2007/11/13/post26.aspx#comments</comments><description>&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;COLOR:#ffffff;FONT-FAMILY:Calibri;BACKGROUND-COLOR:#008000;"&gt;Durante&lt;/span&gt;&lt;font face="Calibri"&gt;&lt;font style="FONT-SIZE:12pt;" size="3"&gt; el &lt;a href="http://msmvps.com/blogs/pmackay/archive/2007/09/27/post20.aspx" target="_blank"&gt;análisis de Microsoft.VisualBasic.dll &lt;/a&gt;tuve problemas para poder ver los contadores de rendimiento de la aplicación desarrollada con Visual Studio 2003 y que se ejecutaba sobre el Framework 1.1, en un sistema XP 64 bits.&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;En ese momento inferí que podría deberse a que la aplicación estaba compilada para 32 bits y se estaba ejecutando en un sistema de 64 bits. Es conveniente recalcar que el Framework 1.1 compila ensamblados sólo para 32 bits.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Hoy, después de un tiempo, me tope con el &lt;a href="http://support.microsoft.com/kb/922775/en-us" target="_blank"&gt;KB 922775&lt;/a&gt;. Para mi sorpresa, tiene un punto dedicado al problema que se me presentó (&lt;em&gt;You cannot monitor 32-bit managed programs in the 64-bit version of Perfmon&lt;/em&gt;). En éste, se presenta un &lt;em&gt;workaround&lt;/em&gt; para poder monitorear contadores de rendimiento de aplicaciones de 32 bits corriendo en sistemas de 64 bits.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Además tiene información relevante para reconstruir los contadores si alguna vez se corrompen.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;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=1307811" 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><category domain="http://msmvps.com/blogs/pmackay/archive/tags/.net/default.aspx">.net</category></item><item><title>Predicando con el ejemplo</title><link>http://msmvps.com/blogs/pmackay/archive/2007/10/30/post24.aspx</link><pubDate>Mon, 29 Oct 2007 23:28:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1274148</guid><dc:creator>pmackay</dc:creator><slash:comments>0</slash:comments><comments>http://msmvps.com/blogs/pmackay/archive/2007/10/30/post24.aspx#comments</comments><description>&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;COLOR:#ffffff;FONT-FAMILY:Calibri;BACKGROUND-COLOR:#008000;"&gt;Predicar&lt;/span&gt;&lt;font face="Calibri"&gt;&lt;font style="FONT-SIZE:12pt;" size="3"&gt; con el ejemplo. Hemos escuchado eso desde chicos. A veces es difícil lograrlo, pero el hacerlo trae beneficios de diferente índole.&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;El tema de esta oportunidad está relacionado con los mensajes de error. Uno de los tantos posibles problemas de seguridad de las aplicaciones es la revelación de &lt;em&gt;&lt;strong&gt;más información de la necesaria&lt;/strong&gt;&lt;/em&gt; cuando se produce un error.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Lo anterior significa que si la aplicación se cae, le informe al usuario pero no le dé mayor información al respecto, información que además es &lt;em&gt;&lt;strong&gt;inútil para el usuario ordinario&lt;/strong&gt;&lt;/em&gt;, pero útil para quien te quiera atacar.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Más información de esta vulnerabilidad podrán encontrar en el sitio del proyecto OWASP, en el siguiente &lt;a href="http://www.owasp.org/index.php/Top_10_2007-A6" target="_blank"&gt;link&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Hace un par de días estaba utilizando OWA de la empresa donde trabajo y de pronto, me topo con esta ventana. Haz clic en ella para verla completa.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;a href="http://msmvps.com/blogs/pmackay/post24/24-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="181" src="http://msmvps.com/blogs/pmackay/post24/24-01s.png" width="347" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Mal, mal. A predicar con el ejemplo. OWA no debiera mostrar este tipo de ventanas de error.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Buenos ejemplos&lt;/strong&gt;&lt;/span&gt;&lt;strong&gt;&amp;nbsp;&lt;/strong&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Veamos algunas pantallas de error donde sí se han tomado las precauciones.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Esta es la de la aplicación que utilizamos en el blog de msmvps.com. Muy divertida, aunque el administrador podría sentirse ofendido.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;a href="http://msmvps.com/blogs/pmackay/post24/24-02b.png"&gt;&lt;img style="BORDER-TOP-WIDTH:0px;BORDER-LEFT-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-RIGHT-WIDTH:0px;" height="150" src="http://msmvps.com/blogs/pmackay/post24/24-02s.png" width="406" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Google también cumple con las buenas prácticas.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&lt;a href="http://msmvps.com/blogs/pmackay/post24/24-03b.png" target="_blank"&gt;&lt;img height="100" src="http://msmvps.com/blogs/pmackay/post24/24-03s.png" width="191" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Malos ejemplos&amp;nbsp;&lt;/strong&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;El típico error de asp.net, cuando el desarrollador y administrador no&amp;nbsp;han tomado las medidas necesarias para que no le llegue al usuario final.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&lt;a href="http://msmvps.com/blogs/pmackay/post24/24-05b.jpg" target="_blank"&gt;&lt;img style="BORDER-TOP-WIDTH:0px;BORDER-LEFT-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-RIGHT-WIDTH:0px;" height="296" src="http://msmvps.com/blogs/pmackay/post24/24-05s.jpg" width="332" alt="" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;y para el final, el peor de todos, cuando se cae leyendo el archivo de configuración y se muestra el contenido de éste.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&lt;a href="http://msmvps.com/blogs/pmackay/post24/24-05b.jpg" target="_blank"&gt;&lt;img style="BORDER-TOP-WIDTH:0px;BORDER-LEFT-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-RIGHT-WIDTH:0px;" height="250" src="http://msmvps.com/blogs/pmackay/post24/24-04b.png" width="414" alt="" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Corrección&lt;/strong&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;¿Cómo corregirlo?&amp;nbsp;Muy fácil.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Para que no se muestre el error en ASP.NET se puede utilizar el elemento Error en la configuración. Más información en este link: &lt;a href="http://msdn2.microsoft.com/en-us/library/s2f4e3e7.aspx" target="_blank"&gt;http://msdn2.microsoft.com/en-us/library/s2f4e3e7.aspx&lt;/a&gt;.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Para modificar IIS para que no muestre el contenido en los errores no controlados se pueden seguir los pasos detallados en este KB: &lt;a href="http://support.microsoft.com/kb/302570/en-us" target="_blank"&gt;http://support.microsoft.com/kb/302570/en-us&lt;/a&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;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=1274148" 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/Seguridad/default.aspx">Seguridad</category></item><item><title>Se viene un momento histórico...</title><link>http://msmvps.com/blogs/pmackay/archive/2007/10/20/post23.aspx</link><pubDate>Sat, 20 Oct 2007 14:05:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1252613</guid><dc:creator>pmackay</dc:creator><slash:comments>4</slash:comments><comments>http://msmvps.com/blogs/pmackay/archive/2007/10/20/post23.aspx#comments</comments><description>&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;COLOR:#ffffff;FONT-FAMILY:Calibri;BACKGROUND-COLOR:#008000;"&gt;Es&lt;/span&gt;&lt;font face="Calibri"&gt;&lt;font style="FONT-SIZE:12pt;" size="3"&gt; cosa de meses; ¿Cuántos?, ¿dos? ¿tres?, no sé, pero falta poco para un momento histórico. Más sitios corriendo sobre IIS que sobre ningún otro servidor web.&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;La información de &lt;a href="http://news.netcraft.com/archives/web_server_survey.html" target="_blank"&gt;Netcraft&lt;/a&gt; muestra para el mes de octubre lo siguiente.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;img height="510" src="http://msmvps.com/blogs/pmackay/post23/23-03b.png" width="562" alt="" /&gt;&lt;/p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Solo un 10% de diferencia entre sitios corriendo Apache e IIS. Considerando una tasa promedio de los últimos 3 meses, en donde IIS sube un 1,41% mensual y apache baja un 1,65% mensual, debiera invertirse la situación en un poco mas de tres meses. Google podría tener algo que decir también.&lt;br /&gt;&lt;br /&gt;En tres meses más lo vemos &lt;img src="http://msmvps.com/emoticons/emotion-5.gif" alt="Wink" /&gt;&lt;br /&gt;&lt;br /&gt;Los meses anteriores mostraron esta información, para agosto y septiembre respectivamente.&lt;br /&gt;&lt;br /&gt;&lt;img height="530" src="http://msmvps.com/blogs/pmackay/post23/23-01b.png" width="582" alt="" /&gt;&lt;br /&gt;&lt;img height="510" src="http://msmvps.com/blogs/pmackay/post23/23-02b.png" width="562" alt="" /&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp; 
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Saludos, 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=1252613" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/pmackay/archive/tags/Personales/default.aspx">Personales</category></item><item><title>Pantallas Azules, ¿hasta cuando?</title><link>http://msmvps.com/blogs/pmackay/archive/2007/10/15/post22.aspx</link><pubDate>Mon, 15 Oct 2007 18:33:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1247883</guid><dc:creator>pmackay</dc:creator><slash:comments>16</slash:comments><comments>http://msmvps.com/blogs/pmackay/archive/2007/10/15/post22.aspx#comments</comments><description>&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;COLOR:#ffffff;FONT-FAMILY:Calibri;BACKGROUND-COLOR:#008000;"&gt;Seguramente&lt;/span&gt;&lt;font face="Calibri"&gt;&lt;font style="FONT-SIZE:12pt;" size="3"&gt; al leer el título de este post pensaste en que me voy a referir a las pantallas azules de Windows. Correcto. También puedes haber pensado que es un post para criticarlas. Bueno, eso no será así. Este post tiene como objetivo explicarlas.&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Historia&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Hace ya un par de años, leí un recorte en el típico mural de las empresas, que estaba escrito por alguien conocido por mí y un referente nacional en muchos aspectos.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;El artículo escrito se llamaba &amp;quot;&lt;a href="http://www.mildiez.net/archivos/2005/07/12/el-software-nuestro-de-cada-dia/" target="_blank"&gt;El software nuestro de cada día&lt;/a&gt;&amp;quot; y estaba escrito por José Miguel Piquer. &lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Jo y Microsoft&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;José Miguel, o &amp;quot;Jo&amp;quot; como le dicen los más cercanos, fue profesor mío en algunos cursos en la carrera de &amp;quot;Ingeniería Civil en Ciencias de la Computación e Informática,&amp;quot; en la Universidad de Chile.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Siempre un gusto ir a sus clases, magister, doctorado y varios títulos más que pueden leer en su &lt;a href="http://www.dcc.uchile.cl/~jpiquer/" target="_blank"&gt;página personal&lt;/a&gt; del Departamento de Ciencias de la Computación (DCC), le recuerdo como acérrimo detractor de Microsoft y Windows.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Artículo&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Bueno, el inicio del artículo escrito por él, esboza la siguiente frase:&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;em&gt;Hay que aceptar que resulta extremadamente frustrante enfrentarse a sistemas que se caen: desde &lt;strong&gt;las pantallas azules clásicas de Windows&lt;/strong&gt;, pasando por los sitios webs bancarios que no responden, hasta las agendas y sus fatal exceptions que se están volviendo más norma que excepción.&lt;/em&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Después, el artículo va realmente a lo importante que él quiere exponer, pero con ésta introducción cae lamentablemente en facilismos con una frase que no aporta mucho, más que exacerbar el cuento de &lt;em&gt;&amp;quot;nunca acabar&amp;quot;&lt;/em&gt; de las pantallas azules. &lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;El artículo está escrito en julio del 2005, diez años después del festín de pantallas azules que nos daban Windows 95, Windows 98, Windows 98 segunda edición y finalmente (por suerte!) Windows Millenium Edition.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;En mis años de estudiante (93-99) nunca hubo un PC en la universidad (salvo el de la secretaria del DCC), así que dudo que él personalmente se haya enfrentado a un sistema de estos, aunque no es por ahí donde quiero llevar este post.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;em&gt;Profesor, todos esperamos mucho de usted. Por favor, no caiga en frases fáciles. No las necesita. Usted está lejos de ser un político.&lt;/em&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;En el año 2005, ya existía Windows 2003, sistema operativo que casi no presentaba pantallas azules. Más aún, en 4 años, no recuerdo haber visto una pantalla azul en Windows 2003, experiencia que seguramente tú compartes.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;¿Son las pantallas azules exclusivas de Windows?&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Casi. En los otros sistemas operativos no son necesariamente azules.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Pantallas azules de diferentes sistemas operativos&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&amp;nbsp;Hagamos una revisión de las pantallas y los sistemas operativos.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Tenemos la clásica de Windows 9X.&lt;br /&gt;&lt;a href="http://msmvps.com/blogs/pmackay/post22/22-01b.jpg" target="_blank"&gt;&lt;img style="BORDER-TOP-WIDTH:0px;BORDER-LEFT-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-RIGHT-WIDTH:0px;" height="123" src="http://msmvps.com/blogs/pmackay/post22/22-01s.jpg" width="256" alt="" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;¿Mac OS?, por supuesto que sí, aunque tienen una diferencia con las de Windows. Son más bonitas y mejor logradas, pero el mensaje no dice nada útil, y que el usuario no pueda intuir que tiene que hacer.&lt;/p&gt;
&lt;table class=""&gt;

&lt;tr&gt;
&lt;td class=""&gt;&lt;a href="http://msmvps.com/blogs/pmackay/post22/22-02b.jpg" target="_blank"&gt;&lt;img style="BORDER-TOP-WIDTH:0px;BORDER-LEFT-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-RIGHT-WIDTH:0px;" height="206" src="http://msmvps.com/blogs/pmackay/post22/22-02s.jpg" width="254" alt="" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td class=""&gt;&lt;a href="http://msmvps.com/blogs/pmackay/post22/22-03b.jpg" target="_blank"&gt;&lt;img style="BORDER-TOP-WIDTH:0px;BORDER-LEFT-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-RIGHT-WIDTH:0px;" height="128" src="http://msmvps.com/blogs/pmackay/post22/22-03s.jpg" width="236" alt="" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Bueno, no siempre son bien logradas, aunque el mensaje es de mayor utilidad que la pantalla anterior.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&lt;a href="http://msmvps.com/blogs/pmackay/post22/22-04b.jpg" target="_blank"&gt;&lt;img style="BORDER-TOP-WIDTH:0px;BORDER-LEFT-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-RIGHT-WIDTH:0px;" height="170" src="http://msmvps.com/blogs/pmackay/post22/22-04s.jpg" width="246" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;¿Linux?, claro que sí, en variadas distribuciones, aunque son llamadas Kernel Panic (un nombre más realista para el problema que analizaremos más adelante).&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&lt;a href="http://msmvps.com/blogs/pmackay/post22/22-05b.jpg" target="_blank"&gt;&lt;img style="BORDER-TOP-WIDTH:0px;BORDER-LEFT-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-RIGHT-WIDTH:0px;" height="197" src="http://msmvps.com/blogs/pmackay/post22/22-05s.jpg" width="249" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://msmvps.com/blogs/pmackay/post22/22-06b.jpg" target="_blank"&gt;&lt;img style="BORDER-TOP-WIDTH:0px;BORDER-LEFT-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-RIGHT-WIDTH:0px;" height="190" src="http://msmvps.com/blogs/pmackay/post22/22-06s.png" width="254" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://msmvps.com/blogs/pmackay/post22/22-07b.jpg" target="_blank"&gt;&lt;img style="BORDER-TOP-WIDTH:0px;BORDER-LEFT-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-RIGHT-WIDTH:0px;" height="176" src="http://msmvps.com/blogs/pmackay/post22/22-07s.jpg" width="260" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;¿Quién esté libre de pecado...&lt;/strong&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;...que lance la primera piedra?, o como dice mi amigo Luisón, el sol sale para todos, y la noche también.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Como ven, no hay sistemas operativos sin fallas, aunque Apple crea y venda lo contrario. Todos enfrentan los mismos problemas. Apple tiene una ventaja en este aspecto sobre Microsoft, la cual se minimizará en el tiempo, mientras se pueda instalar Windows Vista o XP sobre hardware homologado por Apple.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Además, es cosa de leer foros para darse cuenta de que Apple funciona bien con software Apple. Cuando empiezas a instalar software de terceros que no cuentan con buenos procesos de certificación, la situación se equipara.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Vamos a la teoría&lt;/strong&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Considerando la arquitectura de procesadores x86, en el año 1982, con el lanzamiento del 80286, se comienzan a dar los primeros pasos en lo que hoy se conoce como &lt;em&gt;protected mode&lt;/em&gt;.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&lt;em&gt;Protected mode&lt;/em&gt;, provee dentro de un conjunto de características, la existencia de cuatro niveles de privilegio, conocidos también como anillos (rings), numerados desde el 0 al 3.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&lt;img height="216" src="http://msmvps.com/blogs/pmackay/post22/22-08b.png" width="300" alt="" /&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;El anillo 0 tiene acceso irrestricto a todo. El anillo 3 tiene accesos restringidos y acotados. El anillo 1 tiene más restricciones que el 0, pero menos que el 2 y menos que el 3 obviamente.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Anillos y Windows&lt;/strong&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Hoy en día, un sistema Windows 2003 ejecuta código en dos anillos. El 0 y el 3. También corre para XP y 2000. Tengo entendido que Vista utiliza el 0, 2 y 3, pero no lo puedo garantizar.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;En el anillo 0 se ejecuta el &lt;em&gt;Kernel&lt;/em&gt; de Windows, el cual realiza algunas de las actividades listadas a continuación. Administración de memoria, acceso al hardware a través del HAL, acceso a dispositivos utilizando drivers, priorización de actividades, plug and play, acceso a redes utilizando protocolos como TCP/IP o HTTP, etc.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;En el anillo 3 se ejecutan las aplicaciones. Cada vez que una aplicación necesita de alguno de los elementos anteriormente mencionados, y que maneja el &lt;em&gt;Kernel&lt;/em&gt;, necesita solicitárselo a éste ya que la aplicación no tiene permiso para acceder directamente.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Esta solicitud y cambio de contexto entre la aplicación y el &lt;em&gt;Kernel&lt;/em&gt; tiene un costo, el cual fue tratado de minimizar en el pasado, pero las lecciones aprendidas fueron duras.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;¿Por qué se producen?&lt;/strong&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Una pantalla azul en Windows se produce cuando se produce una falla en código que se ejecuta en el &lt;em&gt;Kernel&lt;/em&gt;. &lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Si una aplicación se cae (anillo 3), nuestro amigo &lt;em&gt;Dr. Watson&lt;/em&gt; la atiende y la mata, pero el sistema operativo sigue funcionando sin problema. Hoy en día, Windows te pregunta si deseas enviar el reporte de error a Microsoft, utilizando la aplicación &lt;em&gt;Windows Error Reporting&lt;/em&gt;.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Si el &lt;em&gt;Kernel&lt;/em&gt; falla (anillo 0), no hay remedio ni doctor que te salve. Bueno, &lt;em&gt;Dr. Watson&lt;/em&gt; no salvaba las aplicaciones sino que les aplicaba la eutanasia. Con un &lt;em&gt;Kernel&lt;/em&gt; con alguna excepción, no se puede seguir funcionando. Cualquier intento (teórico) de seguir funcionando podría implicar que se corrompan archivos en el disco, por ejemplo.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Mencionaba hace un rato que en Linux, la pantalla azul se llama &lt;em&gt;Kernel panic&lt;/em&gt;. En efecto, eso es. Es un problema en el &lt;em&gt;Kernel&lt;/em&gt; y no hay mucho más que hacer, salvo entrar en pánico.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;En los SO Windows de hoy, versión 2000 en adelante, los motivos de las pantallas azules son los siguientes. Este gráfico fue generado con datos hasta el mes de Abril del 2004, obtenido del libro &lt;em&gt;Windows Internals&lt;/em&gt; de Solomon y Russinovich.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&lt;img height="258" src="http://msmvps.com/blogs/pmackay/post22/22-09b.png" width="459" alt="" /&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;El 15% desconocido se debe a que el nivel de corrupción en la información obtenida después de la caída es tan grande que no permite identificar ningún responsable. &lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Windows 9X y el festín de las pantallas azules&lt;/strong&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Por algún motivo de diseño, que jamás sabremos el origen, debido al costo del cambio de transición entre el anillo 3 y el 0, los diseñadores de ese sistema operativo consideraron que para mejorar el rendimiento, mucho código del sistema y aplicaciones correrían en el anillo 0.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Debido a esto, el más mínimo error en cualquier aplicación, podría comprometer el sistema completo, como ocurrió en la archiconocida presentación de Windows 98 de Bill Gates. &lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Esa fue una lección de duro aprendizaje.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Drivers&lt;/strong&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Como se pudo ver en el gráfico, el 70% de los problemas son producto de drivers de terceros que corren en el &lt;em&gt;Kernel&lt;/em&gt;, y sólo el 5% es código defectuoso de Microsoft. Me gustaría saber cuál es la tasa actual, al final del 2007.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Cuando nosotros como usuarios instalamos un driver que no está certificado, estamos generando un potencial problema con nuestro computador. Por supuesto, ese driver puede estar muy bien desarrollado y jamás tendremos una pantalla azul.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;En mi caso particular, el driver de mi webcam tiene problemas serios en Windows XP 64 bits. En Windows XP 32 bits funciona sin problema. En 64 bits, cada vez que abro el Messenger y la activo, pantalla azul. ¿Puede ser Messenger el responsable de la caída de mi equipo? Claro que no. Messenger corre en el anillo 3, pero el driver de mi webcam corre en el 0.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Windows Vista&lt;/strong&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Según tengo entendido, en Windows Vista, algunos o todos los drivers de terceros se ejecutan en el anillo 2, es decir, con mayor privilegio que las aplicaciones, pero con menor privilegio que el &lt;em&gt;Kernel&lt;/em&gt;. Esto ayudaría enormemente a minimizar los problemas de pantallas azules producto de drivers defectuosos. Ya sabemos que para abril del 2004, el 70% de los errores reportados era por problemas de drivers defectuosos.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Parte de ésta información se puede encontrar &lt;a href="http://msdn2.microsoft.com/en-us/library/Bb188739.aspx" target="_blank"&gt;aquí&lt;/a&gt; (sección &lt;em&gt;Driver stability in Windows Vista&lt;/em&gt;), pero nada menciona de anillos. Sí menciona que parte del driver corre a nivel de usuario (anillo 3).&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Ventaja de Apple&lt;/strong&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Apple tiene una gran ventaja sobre Microsoft, sin embargo, la posibilidad de instalar Windows sobre un equipo Apple mostrará nuevos aspectos en esta materia.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Como sabemos, el gran problema de Windows son los drivers de terceros. &lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Windows está hecho para que funcione sobre casi cualquier hardware que sea x86, x64 e IA64 compatible. Como hardware me refiero a placas madre, tarjetas de video de dudosa procedencia, memoria de dudosa procedencia, procesadores de segunda generación de Intel, tarjetas de red y cuanto hardware se pueda construir en el mundo.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Por otra parte, el hardware de los equipos Apple está homologado, probado y garantizado para que funcione bien, como piezas de una buena orquesta.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;¿Qué sucede si quiero expandir la memoria de mi Apple? tengo que ir a Apple e instalar la que ellos dicen que funciona.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;¿Qué sucede si quiero expandir la memoria de mi PC?. Voy y compro en la esquina la más económica.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Lo mismo para el resto del hardware, y por ende, los drivers.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Drivers malos, problemas de &lt;em&gt;Kernel&lt;/em&gt;. Problemas de &lt;em&gt;Kernel&lt;/em&gt;, pantallas azules.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Mi amigo Luisón ya instaló Vista en su Mac (también tiene un PC) y dice que anda mucho mejor que en el PC. Yo no puedo atestiguarlo, pero le creo.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Anillo 1&lt;/strong&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Antes de finalizar, una nota anecdótica. El anillo 1 estuvo mucho tiempo sin utilizarse, o al menos eso es lo que yo tengo entendido. Sin embargo, en estos últimos años se ha usado bastante, aunque probablemente no sepas cómo.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Si utilizaste &lt;em&gt;Virtual Server&lt;/em&gt; o &lt;em&gt;Virtual PC&lt;/em&gt;, las máquinas virtuales se ejecutan en el anillo 1. Esto significa que tienen más privilegios que tus aplicaciones, pero menos que el &lt;em&gt;Kernel&lt;/em&gt; del sistema operativo &lt;em&gt;host&lt;/em&gt;. Así, una maquina virtual no podrá hacer caer&amp;nbsp; tu sistema operativo de host.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;¿Anillo -1?&lt;/strong&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Otra nota curiosa. En hardware que soporta virtualización, quien controla la administración de las máquinas virtuales (Hypervisor en Windows 2008) se ejecuta en el anillo -1, para que las máquinas virtuales se ejecuten en los anillos correspondientes a como ha funcionado siempre (0 y 3). Más información en &lt;a href="http://blogs.technet.com/ponicke/archive/2007/05/20/estas-listo-para-lo-que-se-vierne.aspx" target="_blank"&gt;Ponicke Bloguea&lt;/a&gt;.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Espero haber arrojado un poco más de luz sobre el cuénto de nunca acabar de las pantallas azules.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Todos los sistemas operativos mencionados las tienen, y en todos el problema es el mismo. &lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Saludos, 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=1247883" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/pmackay/archive/tags/Windows+y+Microsoft/default.aspx">Windows y Microsoft</category></item><item><title>¿Expresiones regulares?...¿una ayuda por favor?</title><link>http://msmvps.com/blogs/pmackay/archive/2007/10/04/post21.aspx</link><pubDate>Thu, 04 Oct 2007 19:46:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1230049</guid><dc:creator>pmackay</dc:creator><slash:comments>0</slash:comments><comments>http://msmvps.com/blogs/pmackay/archive/2007/10/04/post21.aspx#comments</comments><description>&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;COLOR:#ffffff;FONT-FAMILY:Calibri;BACKGROUND-COLOR:#008000;"&gt;Si&lt;/span&gt;&lt;font face="Calibri"&gt;&lt;font style="FONT-SIZE:12pt;" size="3"&gt; hoy tuviese que dar una lista de las funcionalidades más poderosas de cualquier lenguaje y que son menos usadas, sin duda incluiría en esta lista las expresiones regulares&lt;/font&gt;&lt;/font&gt;.&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Hay que ser honestos y reconocer que existen un par de barreras de entrada importantes para su uso.&lt;/span&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Documentación. No existen muchos sitios dedicados a explicarlas. Hay unos muy buenos, pero son pocos.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Dificultad de aprendizaje. No son triviales.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Si tienes conocimientos básicos de estas y siempre has tenido problemas probando y probando, te recomiendo este sitio. Tiene un probador que usa colores y te muestra si tu información cumple con la expresión definida, y si no lo hace, hasta dónde llega.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;La URL es &lt;a href="http://regexpal.com/" target="_blank"&gt;regexpal.com&lt;/a&gt; y ésta es una imagen de su utilización. Muy útil.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&lt;img src="http://msmvps.com/blogs/pmackay/post21/21-01b.png" alt="" /&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1230049" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/pmackay/archive/tags/Tips/default.aspx">Tips</category></item><item><title>Microsoft.VisualBasic.dll, ¿Eres tan malo como dicen?</title><link>http://msmvps.com/blogs/pmackay/archive/2007/09/27/post20.aspx</link><pubDate>Thu, 27 Sep 2007 01:16:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1218331</guid><dc:creator>pmackay</dc:creator><slash:comments>7</slash:comments><comments>http://msmvps.com/blogs/pmackay/archive/2007/09/27/post20.aspx#comments</comments><description>&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;COLOR:#ffffff;FONT-FAMILY:Calibri;BACKGROUND-COLOR:#008000;"&gt;Algunos&lt;/span&gt;&lt;font face="Calibri"&gt;&lt;font style="FONT-SIZE:12pt;" size="3"&gt; años atrás, todo lo relacionado con Visual Basic (VB) 6.0 tendía a ser menospreciado o subvalorado. Los desarrolladores que utilizábamos VB 6.0 no éramos los primeros en levantar la mano para decir orgullosos que lo utilizábamos, como sí lo hacían los que usaban C o C++.&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Una pequeña fracción de esa baja estima se mantuvo aún cuando apareció .net. Era cierto que teníamos un nuevo lenguaje (o un lenguaje muy remozado) que permitía lograr cosas impensadas en VB 6.0, tales como programar realmente orientado a objetos, crear &lt;em&gt;threads&lt;/em&gt;, o deshacernos por fin de los problemas de los componentes marcados como &lt;em&gt;Apartment&lt;/em&gt;, pero seguía existiendo &amp;quot;algo.&amp;quot;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;A mi entender, algunos de los problemas que NO ayudaron a la transición real de un lenguaje limitado a un lenguaje completo, se pueden desglosar en la siguiente lista:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;La existencia &lt;em&gt;Option Explicit&lt;/em&gt; en vb.net. No existe programación seria sin declaración e inicialización de variables. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;La existencia de &lt;em&gt;Option Strict&lt;/em&gt; en vb.net.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&lt;em&gt;Microsoft.VisualBasic.dll&lt;/em&gt;, librería para ayudar a la migración de proyectos, que implementa esas terribles funciones como &lt;em&gt;Len&lt;/em&gt;, &lt;em&gt;Left&lt;/em&gt;, &lt;em&gt;Right&lt;/em&gt;, &lt;em&gt;Trim&lt;/em&gt;, &lt;em&gt;Mid&lt;/em&gt;, &lt;em&gt;Replace&lt;/em&gt; y otras.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Respecto a este último punto, siempre que tenía la dicha de ver algún proyecto usándola, terminaba recomendado que no se use y que use las propiedades de los tipos de .net. (Ej: en vez de usar &lt;em&gt;Len(variable)&lt;/em&gt; usar &lt;em&gt;variable.length)&lt;/em&gt;. &lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Ante la obvia pregunta de ¿por qué no debo usarla?, venía una respuesta que obtuve de variados lugares, pero nunca comprobé empíricamente, y que sostenía que tenía menor rendimiento que las nativas de los tipos.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;A veces incluso utilizaba &lt;a href="http://www.aisto.com/roeder/dotnet/"&gt;Reflector&lt;/a&gt; para justificar mi teoría, como muestro en la siguiente imagen. ¿Para qué usar &lt;em&gt;Trim(variable)&lt;/em&gt; si al final lo que se ejecuta es &lt;em&gt;variable.trim&lt;/em&gt;? Mejor hacerlo directamente.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;img height="298" src="http://msmvps.com/blogs/pmackay/post20/20-01b.png" width="323" alt="" /&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;En esta oportunidad he decidido hacer pruebas sobre las funciones más utilizadas de VB 6.0, pero que fueron reescritas en este ensamblado (&lt;em&gt;Microsoft.VisualBasic.dll&lt;/em&gt;) y determinar bajo pruebas empíricas si son &amp;quot;tan&amp;quot; malas como aparentan.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Quiero hacer hincapié en algo muy importante. Las funciones antes mencionadas, implementadas en VB 6.0, y que califiqué como &amp;quot;terribles&amp;quot;, justifican el calificativo asignado. Muchas de ellas, si es que no todas, reciben como parámetro de entrada un tipo de datos &lt;em&gt;variant&lt;/em&gt; y retornan un tipo &lt;em&gt;variant&lt;/em&gt;. &lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Esta conversión a &lt;em&gt;variant&lt;/em&gt; penaliza el rendimiento de la aplicación, y peor aún, si se realiza en en ambos sentidos (entrada y salida). Siempre hablando en el contexto de VB 6.0, algunas funciones tenían variantes que terminaban en $, como &lt;em&gt;Left&lt;/em&gt;$, y que tenían la gracia de retornar un tipo &lt;em&gt;string&lt;/em&gt;, pero seguían recibiendo un &lt;em&gt;variant&lt;/em&gt;. No entiendo que costaba hacer una que recibiese &lt;em&gt;string&lt;/em&gt; y retornase &lt;em&gt;string&lt;/em&gt;, pero ya está. Ya fue.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Por suerte, ahora en .net, las implementaciones en &lt;em&gt;Microsoft.VisualBasic.dll&lt;/em&gt; incluyen parámetros correctamente tipificados, con la consecuente mejora en rendimiento. &lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Vamos a la prueba y a los sorprendentes resultados.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Código a ejecutar&lt;/strong&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Todas las funciones a medir fueron llamadas desde una única función general para cada lenguaje, llamadas &lt;em&gt;ProcesarComoVB6&lt;/em&gt; y &lt;em&gt;ProcesarComoVBNET&lt;/em&gt;. No es mi intención medir y comparar el rendimiento de cada función específica sino que medir en general que sucede si se utilizan funciones de &lt;em&gt;Microsoft.VisualBasic.dll&lt;/em&gt; o las nativas de los tipos en forma directa.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Cada función general recibe una cadena de 41.000 bytes y la procesa siguiendo la misma regla, detallada en el código de más abajo.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;El siguiente es el código a ejecutar, utilizando &lt;em&gt;Microsoft.VisualBasic.dll&lt;/em&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&lt;img height="193" src="http://msmvps.com/blogs/pmackay/post20/20-02b.Png" width="405" alt="" /&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;El mismo código, utilizando las llamadas nativas de los tipo&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&lt;img height="212" src="http://msmvps.com/blogs/pmackay/post20/20-03b.Png" width="435" alt="" /&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;La prueba comprende la ejecución una cantidad de 200 veces cada una de las funciones, midiendo los tiempos en terminar de procesar todas las instrucciones. Antes de iniciar las 200 iteraciones de cada una de las funciones, estas son llamadas un par de veces antes para &lt;em&gt;JITtearlas&lt;/em&gt; (bonita palabra, no?)&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Resultados de las pruebas&lt;/strong&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Ejecutando la prueba en un proyecto desarrollado en Visual Studio 2003 con el Framework 1.1, compilado en modo &lt;em&gt;release&lt;/em&gt;, se obtienen los resultados de la siguiente tabla:&lt;/p&gt;
&lt;table class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;WIDTH:100%;BORDER-BOTTOM:#008000 1px solid;" cellspacing="0" cellpadding="0"&gt;

&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;COLOR:#ffffff;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;BACKGROUND-COLOR:#008000;"&gt;Ejecución N°&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;COLOR:#ffffff;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;BACKGROUND-COLOR:#008000;"&gt;Microsoft.VisualBasic.dll&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;COLOR:#ffffff;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;BACKGROUND-COLOR:#008000;"&gt;Métodos nativos&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;1&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;28,51 segundos&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;16,20 segundos&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;2&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;27,76 segundos&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;16,15 segundos&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;3&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;30,45 segundos&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;17,40 segundos&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Wow...(no estoy haciendo propaganda a Vista &lt;img src="http://msmvps.com/emoticons/emotion-5.gif" alt="Wink" /&gt;), impresionante. No nos engañemos todavía. Aún hay mucho que descubrir.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Analicemos antes de seguir las funciones que estamos midiendo y qué podría justificar la diferencia.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Tanto &lt;em&gt;Left&lt;/em&gt;, &lt;em&gt;Right&lt;/em&gt; como &lt;em&gt;Mid&lt;/em&gt; debieran tener costos similares a la representación en VB.NET utilizando &lt;em&gt;Substring&lt;/em&gt;. Técnicamente lo que hacen es obtener un grupo de caracteres de una cadena. No hay mucha ciencia.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Conversiones de caracteres a números y viceversa no son costosos, o no debieran serlo. Entonces, &lt;em&gt;Convert.ToChar&lt;/em&gt; y &lt;em&gt;Convert.ToInt32&lt;/em&gt; debieran tener similar rendimiento a &lt;em&gt;Asc&lt;/em&gt; y &lt;em&gt;Chr&lt;/em&gt; respectivamente. Esto último no es necesariamente cierto para el resultado de la transformación. Los resultados de &lt;em&gt;Asc&lt;/em&gt; y &lt;em&gt;Chr&lt;/em&gt; pueden diferir de los de Convert.* de acuerdo a la cultura que se utilice.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;¿Que nos queda?...&lt;em&gt;Replace&lt;/em&gt;...el dolor de cabeza de un procesador....&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Nuevas pruebas, sin &lt;/strong&gt;&lt;em&gt;&lt;strong&gt;Replace&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;El siguiente es el resultado de las pruebas removiendo el&lt;em&gt; Replace&lt;/em&gt; del final, de ambas funciones. Los resultados son nuevamente sorprendentes.&lt;/p&gt;
&lt;table class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;WIDTH:100%;BORDER-BOTTOM:#008000 1px solid;" cellspacing="0" cellpadding="0"&gt;

&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;COLOR:#ffffff;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;BACKGROUND-COLOR:#008000;"&gt;Ejecución N°&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;COLOR:#ffffff;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;BACKGROUND-COLOR:#008000;"&gt;Microsoft.VisualBasic.dll&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;COLOR:#ffffff;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;BACKGROUND-COLOR:#008000;"&gt;Métodos nativos&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;1&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;7,59 segundos&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;7,46 segundos&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;2&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;9,20 segundos&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;8,73 segundos&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;3&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;8,98 segundos&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;8,07 segundos&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Interesante, no? ¿Qué se puede concluir ahora?&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Conclusiones aventuradas&lt;/strong&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Descartando la función &lt;em&gt;Replace&lt;/em&gt;, como supusimos, no hay mucha diferencia en el tiempo entre utilizar el ensamblado &lt;em&gt;Microsoft.VisualBasic.dll&lt;/em&gt; y las funciones nativas. &lt;em&gt;Replace&lt;/em&gt; hace la diferencia. Veamos por qué.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Si se utiliza &lt;a href="http://www.aisto.com/roeder/dotnet/"&gt;Reflector&lt;/a&gt; para ver el código de &lt;em&gt;String.Replace&lt;/em&gt; se obtiene esto.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&lt;img height="51" src="http://msmvps.com/blogs/pmackay/post20/20-04b.Png" width="451" alt="" /&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Si se utiliza Reflector para ver el código de &lt;em&gt;Replace&lt;/em&gt; desde &lt;em&gt;Microsoft.VisualBasic.dll&lt;/em&gt;, se obtiene esto, y pongan atención a la zona enmarcada en rojo. Ouch!! Eso afecta cualquier procesador.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&lt;img height="386" src="http://msmvps.com/blogs/pmackay/post20/20-05b.Png" width="469" alt="" /&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Más aún, &lt;em&gt;Strings.Split&lt;/em&gt; y &lt;em&gt;String.Join&lt;/em&gt; son funciones implementadas en &lt;em&gt;Microsoft.VisualBasic.dll&lt;/em&gt; y no las nativas del tipo &lt;em&gt;string&lt;/em&gt;.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Consumo de recursos&lt;/strong&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Veamos ahora como anda el consumo de recursos y uso del procesador para cada ejecución. Para eso utilizaremos performance monitor y revisaremos contadores de CPU, proceso, excepciones en .net y memoria en .net.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Los contadores a medir son:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Uso del procesador para el proceso, tanto para tiempo de proceso de usuario como de &lt;em&gt;kernel&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Excepciones lanzadas por segundo&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Colecciones en cada generación&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Colecciones inducidas&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Total de bytes utilizados&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Bytes pedidos por segundo&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Tiempo utilizado por el GC&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Bytes privados del proceso&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Grande fue mi sorpresa cuando los contadores de rendimiento de la memoria en .net, todos marcaban cero durante la ejecución. ¿El motivo? No se si es el motivo &amp;quot;oficial,&amp;quot; pero al menos a mi me bastó como auto-explicación. El Framework 1.1 no corre de forma nativa en 64 bits ya que este sólo puede generar código ensamblado de 32 bits. Como mi sistema operativo es 64 bits, es posible que la instrumentación de 1.1 no funcione. Por lo tanto, a mover todo al Framework 2.0 y Visual Studio 2005.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&lt;em&gt;Nota: Si te preguntas por que no hice todo el post utilizando 2.0, la respuesta es porque quería mostrar cual es el impacto de correr aplicaciones 32 bits sobre 64 bits emulando 32, tanto para el Framework 1.1 como 2.0. También haré la prueba con 2.0 compilado en 32 bits, que es lo que viene justo ahora.&lt;/em&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Compilando para 32 bits (x86) una aplicación .net 2.0&lt;/strong&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;En esta oportunidad no haremos mucho análisis. Me interesa dejar los tiempos como referencia y poder comparar en los diferentes ambientes.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Versión con &lt;em&gt;Replace&lt;/em&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;
&lt;table class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;WIDTH:100%;BORDER-BOTTOM:#008000 1px solid;" cellspacing="0" cellpadding="0"&gt;

&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;COLOR:#ffffff;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;BACKGROUND-COLOR:#008000;"&gt;Ejecución N°&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;COLOR:#ffffff;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;BACKGROUND-COLOR:#008000;"&gt;Microsoft.VisualBasic.dll&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;COLOR:#ffffff;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;BACKGROUND-COLOR:#008000;"&gt;Métodos nativos&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;1&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;23,32 segundos&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;25,15 segundos&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;2&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;23,29 segundos&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;25,16 segundos&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;3&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;23,28 segundos&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;25,46 segundos&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Versión sin &lt;em&gt;Replace&lt;/em&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;
&lt;table class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;WIDTH:100%;BORDER-BOTTOM:#008000 1px solid;" cellspacing="0" cellpadding="0"&gt;

&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;COLOR:#ffffff;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;BACKGROUND-COLOR:#008000;"&gt;Ejecución N°&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;COLOR:#ffffff;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;BACKGROUND-COLOR:#008000;"&gt;Microsoft.VisualBasic.dll&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;COLOR:#ffffff;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;BACKGROUND-COLOR:#008000;"&gt;Métodos nativos&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;1&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;7,40 segundos&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;7,37 segundos&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;2&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;7,17 segundos&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;7,09 segundos&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;3&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;7,18 segundos&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;7,78 segundos&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;¿Conclusiones?...mmm, no gracias.. No tengo nada inteligente que aportar, como tampoco quiero hacer suposiciones. Full 64 bits por favor!!&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Compilando para 64 bits (x64) una aplicación .net 2.0&lt;/strong&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Veamos los resultados de la misma prueba compilado para 64, o mejor dicho, compilado para cualquier CPU. Total, una vez que se &lt;em&gt;JITtee&lt;/em&gt; (bonita palabra nuevamente, no?), lo hará para el procesador en que se está ejecutando.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Versión con &lt;em&gt;Replace&lt;/em&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;
&lt;table class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;WIDTH:100%;BORDER-BOTTOM:#008000 1px solid;" cellspacing="0" cellpadding="0"&gt;

&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;COLOR:#ffffff;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;BACKGROUND-COLOR:#008000;"&gt;Ejecución N°&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;COLOR:#ffffff;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;BACKGROUND-COLOR:#008000;"&gt;Microsoft.VisualBasic.dll&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;COLOR:#ffffff;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;BACKGROUND-COLOR:#008000;"&gt;Métodos nativos&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;1&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;14,07 segundos&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;19,35 segundos&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;2&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;13,98 segundos&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;18,79 segundos&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;3&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;14,25 segundos&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;19,12 segundos&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Versión sin &lt;em&gt;Replace&lt;/em&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;
&lt;table class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;WIDTH:100%;BORDER-BOTTOM:#008000 1px solid;" cellspacing="0" cellpadding="0"&gt;

&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;COLOR:#ffffff;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;BACKGROUND-COLOR:#008000;"&gt;Ejecución N°&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;COLOR:#ffffff;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;BACKGROUND-COLOR:#008000;"&gt;Microsoft.VisualBasic.dll&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;COLOR:#ffffff;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;BACKGROUND-COLOR:#008000;"&gt;Métodos nativos&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;1&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;5,86 segundos&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;5,96 segundos&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;2&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;5,93 segundos&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;5,68 segundos&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;3&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;5,79 segundos&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;5,75 segundos&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;¿¿¿¿Qué???? &lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Parece que el equipo de desarrollo de VB.NET se tomó en serio las críticas y decidieron mejorar el producto.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Veamos con reflector el código de &lt;em&gt;Replace&lt;/em&gt; de &lt;em&gt;Microsoft.VisualBasic.dll&lt;/em&gt;, para la versión 2.0 del Framework.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&lt;img height="428" src="http://msmvps.com/blogs/pmackay/post20/20-06b.Png" width="472" alt="" /&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Interesante. Cambiaron esa idea de hacer &lt;em&gt;splits&lt;/em&gt; y &lt;em&gt;joins&lt;/em&gt; e implementaron una función con ese fin específico. &lt;em&gt;ReplaceInternal&lt;/em&gt; utiliza un &lt;em&gt;Stringbuilder&lt;/em&gt; para cumplir su labor. Bien.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Volvamos ahora que tenemos contadores al análisis del consumo de recursos.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Consumo de recursos, V 2.0&lt;/strong&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Analicemos la utilización de recursos para ambas versiones, con y sin &lt;em&gt;Replace&lt;/em&gt;. En todos los contadores colocaré el valor por defecto, que en algunos casos es el promedio y otros el máximo.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Versión con &lt;em&gt;Replace&lt;/em&gt;&lt;/p&gt;
&lt;table class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;WIDTH:100%;BORDER-BOTTOM:#008000 1px solid;" cellspacing="0" cellpadding="0"&gt;

&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;COLOR:#ffffff;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;BACKGROUND-COLOR:#008000;"&gt;Contador&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;COLOR:#ffffff;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;BACKGROUND-COLOR:#008000;"&gt;Microsoft.VisualBasic.dll&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;COLOR:#ffffff;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;BACKGROUND-COLOR:#008000;"&gt;Métodos nativos&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;# Exceptions Thrown/sec&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;0&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;0&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;# Gen 0 Collections&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;23.236&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;15.134&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;# Gen 1 Collections&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;2&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;61&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;# Gen 2 Collections&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;0&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;12&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;# Induced GC&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;0&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;0&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;# Total Commited Bytes&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;1,3 MB&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;3 MB&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;% Time en GC&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;7,1 %&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;2,8 %&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;Allocated bytes/sec&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;1,1 GB (así es)&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;512 MB&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;% User Time&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;89 %&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;85 %&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;% Privileged Time&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;3 %&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;12 %&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;Private Bytes&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;23 MB&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;24,8 MB&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&lt;em&gt;Mini conclusiones versión con Replace&lt;/em&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;La utilización de métodos nativos consume menos recursos en general. Hay una reducción importante en las recolecciones de primera generación (gen 0), pero las recolecciones en esa generación son muy económicas, al igual que las de la generación 1. Las de generación 2 son caras y hay que evitarlas, aunque 12 es un número pequeño. &lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Lo anterior se traduce en que la versión con métodos nativos consume menos procesador recolectando &amp;quot;basura,&amp;quot; y genera mucho menos &amp;quot;basura&amp;quot; (&lt;em&gt;Allocated bytes/sec&lt;/em&gt;).&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;En la versión con métodos nativos, podría existir una relación entre la cantidad de &lt;em&gt;bytes commited&lt;/em&gt; y la cantidad de recolecciones de segunda y tercera generación (gen 1 y gen 2) ya que hay memoria que se mantiene ocupada más tiempo y no es liberada en recolecciones de primera generación. Esto es solo una suposición.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Versión sin &lt;em&gt;Replace&lt;/em&gt;&lt;/p&gt;
&lt;table class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;WIDTH:100%;BORDER-BOTTOM:#008000 1px solid;" cellspacing="0" cellpadding="0"&gt;

&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;COLOR:#ffffff;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;BACKGROUND-COLOR:#008000;"&gt;Contador&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;COLOR:#ffffff;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;BACKGROUND-COLOR:#008000;"&gt;Microsoft.VisualBasic.dll&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;COLOR:#ffffff;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;BACKGROUND-COLOR:#008000;"&gt;Métodos nativos&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;# Exceptions Thrown/sec&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;0&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;0&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;# Gen 0 Collections&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;14.305&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;12.654&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;# Gen 1 Collections&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;0&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;52&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;# Gen 2 Collections&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;0&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;10&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;# Induced GC&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;0&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;0&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;# Total Commited Bytes&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;1,3 MB&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;3 MB&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;% Time en GC&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;9,3 %&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;8,2 %&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;Allocated bytes/sec&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;2,0 GB&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;1,5 GB&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;% User Time&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;93 %&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;94 %&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;% Privileged Time&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;4 %&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;4 %&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;Private Bytes&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;23,5 MB&lt;/td&gt;
&lt;td class="" style="BORDER-RIGHT:#008000 1px solid;BORDER-TOP:#008000 1px solid;BORDER-LEFT:#008000 1px solid;BORDER-BOTTOM:#008000 1px solid;FONT-FAMILY:Calibri;"&gt;25,9 MB&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&lt;em&gt;Mini conclusiones versión sin Replace&lt;/em&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;El consumo de recursos es equivalente. Llama la atención el aumento en ambas versiones de la cantidad de bytes pedidos por segundo (&lt;em&gt;allocated&lt;/em&gt;&lt;em&gt; bytes/sec&lt;/em&gt;). &lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;El resto de los contadores no presenta diferencias importantes entre ambas funciones para la versión sin &lt;em&gt;Replace&lt;/em&gt;.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Conclusiones&lt;/strong&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Las siguientes conclusiones puedo obtener del análisis.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;1.- No correr aplicaciones 1.1 en 64 bits&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;2.- No correr aplicaciones compiladas para x86 en 64 bits&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Tristemente, mi intención inicial de encontrar algún motivo para que no se utilice &lt;em&gt;Microsoft.VisualBasic.dll&lt;/em&gt; en los proyectos no ha podido ser cumplida. &lt;img src="http://msmvps.com/emoticons/emotion-6.gif" alt="Sad" /&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;En el único escenario donde encarecidamente recomendaría no usarla es en aplicaciones 1.1, pero en aplicaciones 2.0, la diferencia es irrelevante.&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Saludos,&lt;/span&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;br /&gt;Patrick.&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1218331" 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>¿Cómo reducir el costo de un LookUp de SQL Server?</title><link>http://msmvps.com/blogs/pmackay/archive/2007/09/09/post19.aspx</link><pubDate>Sun, 09 Sep 2007 05:53:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1181517</guid><dc:creator>pmackay</dc:creator><slash:comments>3</slash:comments><comments>http://msmvps.com/blogs/pmackay/archive/2007/09/09/post19.aspx#comments</comments><description>&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;font face="Calibri"&gt;&lt;span style="FONT-SIZE:12pt;BACKGROUND:green;COLOR:white;LINE-HEIGHT:115%;mso-themecolor:background1;mso-highlight:green;"&gt;Durante&lt;/span&gt;&lt;font style="FONT-SIZE:12pt;" size="3"&gt; la exposición de nuestra charla de como optimizar consultas de SQL Server, hice bastante hincapié en la relación/dependencia de los índices no agrupados (no clustered) y el agrupado (clustered) de un tabla. En caso de que ésta no cuente con un índice agrupado, existe una relación/dependencia similar pero con una estructura interna de la tabla (RID).&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;En este post veremos qué es un &lt;em&gt;LookUp&lt;/em&gt; (SQL 2005) o &lt;em&gt;Bookmark LookUp&lt;/em&gt; (SQL 2000) y cómo eliminarlos o al menos mitigarlos cuando se pueda. Usaré SQL 20005, pero si tienes 2000, la manera de enfrentarlo es similar.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Antes de ir a la información del caso, haremos un pequeño repaso de lo revisado en la charlas de optimización de consultas.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Relación/dependencia entre índices en una tabla&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Un índice no agrupado almacena, por cada elemento del índice, un &amp;quot;identificador&amp;quot; que dice donde encontrar en la tabla los datos asociados a este ítem del índice. De esta forma, cada vez que SQL Server utiliza el índice no agrupado y determina que debe ir a buscar los datos, utiliza ese &amp;quot;identificador&amp;quot; para ubicar los datos en la tabla.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Si la tabla &lt;span style="TEXT-DECORATION:underline;"&gt;&lt;strong&gt;no&lt;/strong&gt;&lt;/span&gt; tiene un índice agrupado, el identificador utilizado es el identificador de la fila o &lt;em&gt;row id&lt;/em&gt; (en inglés), el cual se representa con las siglas RID. Este RID está compuesto por el numero del archivo de la base de datos, el número de la página dentro de ese archivo y por último, el número de la fila en la página.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Si la tabla &lt;span style="TEXT-DECORATION:underline;"&gt;&lt;strong&gt;sí&lt;/strong&gt;&lt;/span&gt; tiene un índice agrupado, el identificador utilizado es la llave del índice agrupado. La llave del índice agrupado son TODAS las columnas del índice agrupado. Por favor, no confundir la llave del índice con la llave primaria de una tabla, aunque muchas veces tienen el mismo &amp;quot;valor,&amp;quot; en especial cuando la tabla se creó sin darle mayor importancia a este tema.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Para más información, revisa el BOL (&lt;em&gt;Books On Line&lt;/em&gt;) de SQL Server, en la instrucción &lt;em&gt;Create Index&lt;/em&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;&lt;em&gt;Bookmark LookUp&lt;/em&gt; o &lt;em&gt;LookUp&lt;/em&gt; a secas&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;En SQL Server 2000 se le conoce como &lt;em&gt;Bookmark LookUp&lt;/em&gt;. En la versión 2005 se llama solamente &lt;em&gt;LookUp&lt;/em&gt;. La idea es la misma para ambas versiones; El problema es el mismo, las soluciones similares.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;em&gt;LookUp&lt;/em&gt;, traducido al español, significa &lt;em&gt;operación de búsqueda&lt;/em&gt;, y representa exactamente eso. Realiza una operación de búsqueda, con un &amp;quot;identificador&amp;quot; de una fila, para traer más información, de la fila específica, desde la tabla.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;La búsqueda se hace, como ustedes se imaginan, utilizando el RID si la tabla no tiene un índice agrupado, o utilizando la llave del índice agrupado, si la tabla cuenta con uno de ese tipo. La siguiente imagen sirve para aclarar el concepto que se trata de explicar.&lt;/span&gt;&lt;/p&gt;
&lt;table class="" cellspacing="0" cellpadding="0"&gt;

&lt;tr&gt;
&lt;td class=""&gt;&lt;img height="498" src="http://msmvps.com/blogs/pmackay/post19/19-04b.PNG" width="394" alt="" /&gt;&lt;/td&gt;
&lt;td class=""&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Utilizando el índice no agrupado, primero se identifica las filas que cumplen con la condición de filtrado.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Resultado: Celdas amarillas.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Se usan los tres identificadores de filas (rojo, verde y azul) y se realiza la operación de búsqueda en el índice agrupado.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Si la tabla no tiene índice agrupado, la operación es similar, pero usa el RID.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Se retornan los datos faltantes.&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Veamos entonces ahora información del caso. En esta oportunidad reproduciré el escenario en una base de datos de prueba, con unas tablas creadas para la ocasión.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;LookUp muy costoso&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Nota: Hace un tiempo atrás estaba en un curso de optimización de SQL Server y le hice la siguiente pregunta a la instructora: &amp;quot;Si tengo el plan de ejecución de una consulta, y el operador de lookup es responsable de casi el 100% del costo del plan, ¿cómo puedo mejorar el rendimiento de mi consulta?.&amp;quot;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Tristemente, no hubo una respuesta aclaratoria ante mi pregunta, como ocurrió en varias otras además. &lt;em&gt;Hoy en día, retrospectivamente, pienso que la instructora era lo que nosotros acá en Chile llamamos &amp;quot;un Adán&amp;quot;, de Adán y Eva. ¿Por qué?. Porque si a Adán le sacas la hojita, queda desnudo. En este caso, la &amp;quot;hojita&amp;quot; es el &amp;quot;libro del curso.&amp;quot; &lt;/em&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Si has estado tratando de optimizar consultas de SQL, es probable que ya te hayas topado con este problema. ¿Qué hacer cuando la operación &lt;em&gt;LookUp&lt;/em&gt; es muy costosa?&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Antes de comenzar, estructura de tablas&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Para este ejemplo, utilizaremos dos tablas, t1 y t2, con la siguiente estructura cada una&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&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;PADDING-TOP:0cm;BORDER-BOTTOM:black 1pt solid;"&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#1000a0;FONT-FAMILY:Courier New;"&gt;CREATE TABLE [dbo].[t1](&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [c1] [int] IDENTITY(1,1) NOT NULL,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [c2] [varchar](50) NOT NULL,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; CONSTRAINT [PK_t1] PRIMARY KEY CLUSTERED ([c1] ASC) ON [PRIMARY])&lt;br /&gt;ON [PRIMARY]&lt;br /&gt;&lt;br /&gt;CREATE TABLE [dbo].[t2](&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [c1] [int] IDENTITY(1,1) NOT NULL,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [c2] [int] NOT NULL,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [c3] [varchar](50) NOT NULL,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [c4] [tinyint] NOT NULL CONSTRAINT [DF_t5_c4] DEFAULT ((1)),&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [c5] [char](200) NOT NULL CONSTRAINT [DF_t2_c5] DEFAULT (&amp;#39;&amp;#39;),&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; CONSTRAINT [PK_t2_1] PRIMARY KEY CLUSTERED ([c1] ASC) ON [PRIMARY])&lt;br /&gt;ON [PRIMARY]&lt;br /&gt;&lt;br /&gt;CREATE NONCLUSTERED INDEX [idx_c2] ON [dbo].[t2] ([c2] ASC)&lt;br /&gt;ON [PRIMARY]&lt;br /&gt;&lt;br /&gt;ALTER TABLE [dbo].[t2] WITH CHECK &lt;br /&gt;ADD CONSTRAINT [FK_t2_t1] FOREIGN KEY([c2]) REFERENCES [dbo].[t1] ([c1]) &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;La tabla t1 tiene 100.000 registros. La tabla t2 tiene 1.000.000 registros. La consulta que estamos realizando es la siguiente.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&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;PADDING-TOP:0cm;BORDER-BOTTOM:black 1pt solid;"&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#1000a0;FONT-FAMILY:Courier New;"&gt;select t1.c1, t1.c2, t2.c1, t2.c3, t2.c4&lt;br /&gt;from t2 inner join t1 on t2.c2 = t1.c1&lt;br /&gt;where t2.c2 between 1000 and 2000 and t2.c3 like &amp;#39;2%&amp;#39; and t2.c4 = 1&amp;nbsp; &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Con esta consulta, estamos trayendo un cantidad importante de columnas de la tabla t2, como también las dos columnas de la tabla t1. Existe un índice en t2.c2, por lo tanto, el filtro &lt;em&gt;between 1000 and 2000&lt;/em&gt; se realizará utilizando el índice para reducir las filas.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;El siguiente es el plan de ejecución generado, en versión texto y gráfico.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&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;PADDING-TOP:0cm;BORDER-BOTTOM:black 1pt solid;"&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#1000a0;FONT-FAMILY:Courier New;"&gt;&lt;pre&gt;Table &amp;#39;t2&amp;#39;. Scan count 1, logical reads &lt;span style="COLOR:#ffffff;"&gt;&lt;strong&gt;30682&lt;/strong&gt;&lt;/span&gt;, physical reads 0, ...
Table &amp;#39;t1&amp;#39;. Scan count 1, logical reads 6, physical reads 0, ...

Rows    Executes  StmtText
-------------------------------------------------------------------------------------------
561     1         |--Merge Join(Inner Join, MERGE:([test].[dbo].[t1].[c1])=([test].[dbo].[t
1001    1               |--Clustered Index Seek(OBJECT:([test].[dbo].[t1].[PK_t1]), SEEK:([  
561     1               |--Filter(WHERE:([test].[dbo].[t2].[c3] like &amp;#39;2%&amp;#39; AND [test].[dbo].
10010   1                    |--Nested Loops(Inner Join, OUTER REFERENCES:([test].[dbo].[t2
10010   1                         |--Index Seek(OBJECT:([test].[dbo].[t2].[idx_c2]), SEEK:(
10010   &lt;span style="COLOR:#ffffff;"&gt;&lt;strong&gt;10010&lt;/strong&gt;&lt;/span&gt;                     |--Clustered Index Seek(OBJE...]) &lt;span style="COLOR:#ffffff;"&gt;&lt;strong&gt;LOOKUP&lt;/strong&gt;&lt;/span&gt; ORDERED FORWARD)&lt;/pre&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Si miramos la versión gráfica, podremos observar que el 100% del costo del plan esta en la operación &lt;em&gt;lookup&lt;/em&gt;. Notar que hemos marcado algunos textos en blanco arriba, los cuales revisaremos más adelante. Para ver el plan gráfico más grande, haz clic sobre él.&lt;/span&gt;&lt;/p&gt;
&lt;table class="" style="WIDTH:100%;" cellspacing="0" cellpadding="0"&gt;

&lt;tr&gt;
&lt;td class=""&gt;&lt;a href="http://msmvps.com/blogs/pmackay/post19/19-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="65" src="http://msmvps.com/blogs/pmackay/post19/19-05s.png" width="183" alt="" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td class=""&gt;&lt;img height="197" src="http://msmvps.com/blogs/pmackay/post19/19-06b.png" width="274" alt="" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;En el plan gráfico, podemos ver que la operación &lt;em&gt;Key Lookup&lt;/em&gt; es responsable del 100% del costo de plan, con un costo de 22,06 (muy malo para un operador, y en consecuencia para el plan). Complementando con el plan de texto, en éste aparece la palabra LOOKUP, y está usando el índice agrupado (clustered) para recuperar las demás columnas que necesita.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Además, se realizan más de 30.000 lecturas sobre la tabla t2.&amp;nbsp;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;¿Donde está el problema?¿Por qué tiene un costo tan elevado?&lt;/strong&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Una única operación de LookUp es de bajísimo costo, más aún si utiliza un índice para hacer un &lt;em&gt;seek&lt;/em&gt; a una fila específica en la tabla. Sin embargo, si se ejecuta 10.010 veces, la sumatoria de estos costos pequeñísimos pasa a tener relevancia, como es nuestro caso.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;La cantidad de veces que se ejecuta la operación &lt;em&gt;LookUp&lt;/em&gt; se puede ver en 2 partes. Una de ellas es el texto marcado con blanco en el plan de ejecución de texto y la otra es en el &lt;em&gt;Tooltip&lt;/em&gt; amarillo, en &amp;quot;&lt;em&gt;Actual Number of Rows&lt;/em&gt;.&amp;quot;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Solución[es] al problema&lt;/strong&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Existen dos formas de enfrentar este problema, y por supuesto, dependen de cada escenario. &lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Una de ellas, y que no veremos ahora porque no tienen ninguna gracia, es agregar todas las columnas necesarias al índice, y con eso, evitar la operación &lt;em&gt;LookUp&lt;/em&gt;. Si tengo toda la información en el índice, no necesito ir a buscar más columnas a la tabla. Esta no falla nunca, pero uno debe evitar incluir muchas columnas en los índices.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;La segunda solución, y que es mucho más elegante, sólo es posible realizar en un escenario como el que tenemos ahora.&lt;/p&gt;
&lt;table class="" style="WIDTH:100%;" cellspacing="0" cellpadding="0"&gt;

&lt;tr&gt;
&lt;td class=""&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Si miran con detenimiento el plan de ejecución, el operador &lt;em&gt;filter&lt;/em&gt; está filtrando en las columna c3 y c4, aplicando los criterios definidos en la consulta SQL. Esto es esperable.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Más aún, como resultado&amp;nbsp;del filtrado, la cantidad de filas retornadas disminuye (anchos de las flechas de entrada y de salida del &lt;em&gt;filter&lt;/em&gt;). Esto también es esperable, ¿o no?&lt;/p&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class=""&gt;&lt;img src="http://msmvps.com/blogs/pmackay/post19/19-07b.png" alt="" /&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Si todo es esperable, ¿dónde está la gracia?&lt;/strong&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;El costo del operador LookUp es muy alto porque se ejecuta muchas veces, ¿verdad?.&amp;nbsp;¿Qué sucedería si logro reducir la cantidad de veces que deba ejecutarse? Seguramente el costo de la consulta será menor y el rendimiento de ésta mucho mayor.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Para reducir la cantidad de veces que se ejecuta, debo reducir la cantidad de filas que son retornadas luego de que se filtre utilizando el índice idx_c2. Para reducir la cantidad de filas retornadas, agrego una columna más al índice, la que más me ayude a filtrar.&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Debido a que la selectividad de la columna c3 es mejor que la de c4, incluiré sólo&amp;nbsp;la columna c3 en el índice idx_c2. Con eso, reduciré la cantidad de filas que requerirán un lookup de más información. &lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Recuerden que estamos tratando de minimizar el costo del LookUp. Si se quiere suprimir totalmente, se deberán agregar todas las columnas necesarias al índice, solución que deberá dejarse sólo para casos ultra-extremos.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Veamos el plan de ejecución de texto de la misma consulta, pero con el índice idx_c2 incluyendo a la columna c3 además de la c2 que ya tenía.&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;PADDING-TOP:0cm;BORDER-BOTTOM:black 1pt solid;"&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#1000a0;FONT-FAMILY:Courier New;"&gt;&lt;pre&gt;Table &amp;#39;t2&amp;#39;. Scan count 1, logical reads &lt;span style="COLOR:#ffffff;"&gt;&lt;strong&gt;3332&lt;/strong&gt;&lt;/span&gt;, physical reads 0, ...
Table &amp;#39;t1&amp;#39;. Scan count 1, logical reads 6, physical reads 0, ...

Rows    Executes  StmtText
-------------------------------------------------------------------------------------------
561     1         |--Merge Join(Inner Join, MERGE:([test].[dbo].[t1].[c1])=([test].[dbo].[t
1001    1               |--Clustered Index Seek(OBJECT:([test].[dbo].[t1].[PK_t1]), SEEK:([  
561     1               |--Filter(WHERE:([test].[dbo].[t2].[c4] = (1)))
1075    1                    |--Nested Loops(Inner Join, OUTER REFERENCES:([test].[dbo].[t2
1075    1                         |--Index Seek(OBJECT:([test].[dbo].[t2].[idx_c2]), SEEK:(
1075    &lt;span style="COLOR:#ffffff;"&gt;&lt;strong&gt;1075&lt;/strong&gt;&lt;/span&gt;                      |--Clustered Index Seek(OBJE...]) &lt;span style="COLOR:#ffffff;"&gt;&lt;strong&gt;LOOKUP&lt;/strong&gt;&lt;/span&gt; ORDERED FORWARD)&lt;/pre&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;table class="" style="WIDTH:100%;" cellspacing="0" cellpadding="0"&gt;

&lt;tr&gt;
&lt;td class=""&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Ahora sólo ejecutó 1.075 veces el &lt;em&gt;LookUp&lt;/em&gt;. No nos hemos deshecho de él, pero al menos hemos reducido su impacto en el costo de la consulta.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Las lecturas lógicas fueron reducidas desde más de 30.000 a sólo 3.332. Una excelente optimización. &lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;El nuevo costo del operador &lt;em&gt;LookUp&lt;/em&gt; es 3,58, como se puede observar a la derecha en el Tooltip. El costo antes de modificar el índice era de 22,06. Otra excelente reducción en el costo.&lt;/p&gt;&lt;/td&gt;
&lt;td class=""&gt;&lt;img height="195" src="http://msmvps.com/blogs/pmackay/post19/19-08b.png" width="254" alt="" /&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Conclusión&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Hemos visto como minimizar el impacto de la operación LookUp en SQL Server. No vimos como eliminarlo ya que para lograr eso, el camino es directo y simple. A veces no es necesario eliminarlo para mejorar drásticamente el rendimiento de una consulta.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Hasta la próxima, desde Santiago de Chile&lt;br /&gt;Patrick.&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1181517" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/pmackay/archive/tags/SQL+Server/default.aspx">SQL Server</category></item><item><title>Charla de optimización de consultas de SQL</title><link>http://msmvps.com/blogs/pmackay/archive/2007/08/02/post17.aspx</link><pubDate>Wed, 01 Aug 2007 23:03:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1080137</guid><dc:creator>pmackay</dc:creator><slash:comments>3</slash:comments><comments>http://msmvps.com/blogs/pmackay/archive/2007/08/02/post17.aspx#comments</comments><description>&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;font face="Calibri"&gt;&lt;span style="FONT-SIZE:12pt;BACKGROUND:green;COLOR:white;LINE-HEIGHT:115%;mso-themecolor:background1;mso-highlight:green;"&gt;Aunque&lt;/span&gt;&lt;font style="FONT-SIZE:12pt;" size="3"&gt; no ha faltado trabajo, las últimas semanas las pasé preparando material para una charla de optimización de consultas en SQL Server que dimos hace algunos días.&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Ya ha pasado casi una semana desde que dimos la charla, a la cual asistieron, si mal no recuerdo, 139 personas. Todo salió casi perfecto. Nos faltó tiempo para hacer las demos, aunque los asistentes nos aguantaron estoicamente desde las 6:35 pm hasta las 10:15 pm, 3 horas y 40 minutos. Impresionante.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Algo muy gratificador, y que no siempre ocurre lamentablemente, es poder lograr buena interacción con los asistentes. Usualmente no preguntan mucho, pero en esta oportunidad, estimo que se deben haber realizado 30 o más preguntas y contra preguntas. Así da gusto!!.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;La imagen que usamos como ícono de la charla causó risas y simpatía entre nuestros amigos más cercanos. &lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;img src="http://msmvps.com/blogs/pmackay/post17/charla.png" border="1" alt="" /&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;font face="Calibri"&gt;&lt;font style="FONT-SIZE:12pt;" size="3"&gt;Los principales temas abordados fueron:&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Definición de plan de ejecución, como se construye, que elementos influyen en éste, &lt;/span&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Detección de problemas en planes de ejecución&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Evaluación de costos, lecturas lógicas&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Teoría de índices, relaciones entre índice agrupados y no agrupados&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Buenas prácticas, selectividad, estadísticas, &lt;em&gt;fill factor&lt;/em&gt;, entre otras cosas.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;Aquí van algunas fotos de la preparación de la charla, el evento propiamente tal y la celebración al final. No incluí fotos con asistentes porque uno nunca sabe si quieren o no aparecer. Para ver las fotos más grades, pincha en éstas.&lt;/p&gt;
&lt;table class="" style="WIDTH:100%;"&gt;

&lt;tr&gt;
&lt;td class=""&gt;&lt;a href="http://msmvps.com/blogs/pmackay/post17/17-07b.jpg" target="_blank"&gt;&lt;img src="http://msmvps.com/blogs/pmackay/post17/17-07s.jpg" border="1" alt="" /&gt; &amp;nbsp;&lt;/a&gt;&lt;/td&gt;
&lt;td class=""&gt;&lt;a href="http://msmvps.com/blogs/pmackay/post17/17-01b.jpg" target="_blank"&gt;&lt;img src="http://msmvps.com/blogs/pmackay/post17/17-01s.jpg" border="1" alt="" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;&lt;a href="http://msmvps.com/blogs/pmackay/post17/17-02b.jpg" target="_blank"&gt;&lt;img src="http://msmvps.com/blogs/pmackay/post17/17-02s.jpg" border="1" alt="" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td class=""&gt;&lt;a href="http://msmvps.com/blogs/pmackay/post17/17-03b.jpg" target="_blank"&gt;&lt;img src="http://msmvps.com/blogs/pmackay/post17/17-03s.jpg" border="1" alt="" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;&lt;a href="http://msmvps.com/blogs/pmackay/post17/17-04b.jpg" target="_blank"&gt;&lt;img src="http://msmvps.com/blogs/pmackay/post17/17-04s.jpg" border="1" alt="" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td class=""&gt;&lt;a href="http://msmvps.com/blogs/pmackay/post17/17-05b.jpg" target="_blank"&gt;&lt;img src="http://msmvps.com/blogs/pmackay/post17/17-05s.jpg" border="1" alt="" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Si te interesa ver el contenido de la charla, ésta está publicada en &lt;a href="http://www.cafeina.cl"&gt;Cafeina&lt;/a&gt;, precisamente &lt;a href="http://www.cafeina.cl/Cafeina/LinkClick.aspx?fileticket=ic5t4IxQpxo%3d&amp;amp;tabid=36&amp;amp;mid=378" target="_blank"&gt;éste&lt;/a&gt; link.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Estamos viendo de realizar una continuación de la charla, sólo para los registrados de ésta, con el fin de poder terminar las demos y resolver más dudas.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;desde Puyehue, al sur de Chile&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Patrick&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;PD: Esta es la vista desde mi habitación acá en el sur de Chile &lt;img src="http://msmvps.com/emoticons/emotion-1.gif" alt="Smile" /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;img src="http://msmvps.com/blogs/pmackay/post17/17-06b.jpg" border="1" alt="" /&gt; &amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1080137" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/pmackay/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://msmvps.com/blogs/pmackay/archive/tags/Charlas/default.aspx">Charlas</category></item><item><title>Entre las excepciones y la flojera de los desarrolladores</title><link>http://msmvps.com/blogs/pmackay/archive/2007/07/20/post16.aspx</link><pubDate>Fri, 20 Jul 2007 04:07:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1041717</guid><dc:creator>pmackay</dc:creator><slash:comments>5</slash:comments><comments>http://msmvps.com/blogs/pmackay/archive/2007/07/20/post16.aspx#comments</comments><description>&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;font face="Calibri"&gt;&lt;span style="FONT-SIZE:12pt;BACKGROUND:green;COLOR:white;LINE-HEIGHT:115%;mso-themecolor:background1;mso-highlight:green;"&gt;Una&lt;/span&gt;&lt;font style="FONT-SIZE:12pt;" size="3"&gt; de las recomendaciones importantes en el desarrollo de código es la &amp;quot;no utilización de excepciones para evitar realizar validaciones.&amp;quot;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;¿A qué me refiero?&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;A usar try/catch para no tener que escribir código que valide algo. Total, si se cae, en el catch retorno que es falso, si no se cayó, entonces retorno verdadero. Así no es necesario codificar rutinas especiales.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Vamos al caso&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Como ya es costumbre en mi trabajo, y de las buenas costumbres, las pruebas de carga muestran la peor parte de las aplicaciones, y esta no fue la excepción, aunque el culpable era código de un componente de terceros.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Pruebas de carga&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Treinta minutos de ejecución de un script grabado con &lt;a href="http://msdn2.microsoft.com/en-us/library/aa287410(VS.71).aspx"&gt;ACT&lt;/a&gt;, 50 usuarios concurrentes, 30 minutos. No vamos a dar todos los detalles, pero el uso de la CPU estaba &amp;quot;fluctuante&amp;quot;, y tenía unas subidas a 100% por varios segundos.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;El siguiente es el grafico de performance monitor. Como hay más de 30 minutos, los segundos que la aplicación pasaba al 100% solo se ven como picos, pero en algunos casos llegaba a casi 40 segundos.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;img height="316" src="http://msmvps.com/blogs/pmackay/post16/16-01b.png" width="421" border="1" alt="" /&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Te podrá haber llamado la atención que el uso de la CPU está muy extraño, como que no es fluido, considerando que una prueba de carga debiera mantenerla ocupada constantemente. No tengo la explicación ahora, pero al final veremos algo diferente.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Mientras revisaba contadores varios, me llamó la atención la cantidad de excepciones que se producían a veces, por lo tanto, agregué el contador de excepciones y voila!!. Problema encontrado.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;img height="316" src="http://msmvps.com/blogs/pmackay/post16/16-02b.png" width="421" border="1" alt="" /&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Asombrosa similitud, ¿no?&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;A tomar &lt;em&gt;dumps&lt;/em&gt; en las excepciones para ver que está ocurriendo. Mmm, mejor que no. Con 184 excepciones por segundo, reventamos el servidor. Mejor aún, utilizo un archivo de configuración para AdPlus, que viene en &lt;a href="http://www.microsoft.com/whdc/devtools/debugging/default.mspx"&gt;Debugging Tool For Windows&lt;/a&gt;, el cual configuro para obtener información de &lt;em&gt;threads&lt;/em&gt;, &lt;em&gt;threadpool&lt;/em&gt;, &lt;em&gt;stacks&lt;/em&gt; manejados y no manejados y excepciones cuando yo le solicite, que será cuando la CPU esté en 100%. &lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;¿Resultado?&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Esta es parte del &lt;em&gt;stack&lt;/em&gt; no manejado, de un &lt;em&gt;thread&lt;/em&gt; manejado. Como este, habían 10 más, es decir, 11 &lt;em&gt;threads&lt;/em&gt; lanzando excepciones, a una asombrosa tasa de 184 por segundo.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&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;&amp;nbsp;22 Id: 3924.46b8 Suspend: 1 Teb: 7ffa5000 Unfrozen&lt;br /&gt;ChildEBP RetAddr Args to Child &lt;br /&gt;06ece448 7c827ad6 7c8063cb ffffffff 7921ace1 ntdll!KiFastSystemCallRet&lt;br /&gt;06ece44c 7c8063cb ffffffff 7921ace1 00000000 ntdll!NtQueryVirtualMemory+0xc&lt;br /&gt;06ece4ac 7c8123b4 7921ace1 00000000 793e8730 ntdll!RtlIsValidHandler+0x82&lt;br /&gt;06ece520 7c834d44 06ecc000 06ece530 00010007 ntdll!RtlDispatchException+0x78&lt;br /&gt;06ece800 77e52db4 06ece810 050d5008 e0434f4d ntdll!RtlRaiseException+0x3d&lt;br /&gt;06ece860 7921af79 e0434f4d 00000001 00000000 kernel32!RaiseException+0x53&lt;br /&gt;06ece8b8 7921aefc 1194c7f0 00000000 06eceb14 mscorwks!RaiseTheException+0xa0&lt;br /&gt;06ece8e0 7921aeb0 1194c7f0 00000000 06eceb24 mscorwks!RealCOMPlusThrow+0x48&lt;br /&gt;06ece8f0 79218cc2 1194c7f0 00000000 0219d0b4 mscorwks!RealCOMPlusThrow+0xd&lt;br /&gt;06eceb24 792b1893 00000018 00000001 00000000 mscorwks!CreateMethodExceptionObject+0x67b&lt;br /&gt;06eceb58 79274773 00000018 79274778 06ecec08 mscorwks!RealCOMPlusThrow+0x35&lt;br /&gt;06eceb68 79338b01 0216137a 000000e7 06eceb90 mscorwks!StringToNumber+0x7e&lt;br /&gt;06ecec08 04266804 06ecec14 0f1604f0 000000e7 mscorwks!COMNumber::ParseDouble+0x32&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Esta es parte del &lt;em&gt;stack&lt;/em&gt; manejado, del mismo &lt;em&gt;thread&lt;/em&gt;.&lt;/span&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:10pt;COLOR:#1000a0;FONT-FAMILY:Courier New;"&gt;0x06ece908 0x7c834cf4 [FRAME: GCFrame] &lt;br /&gt;0x06ecec38 0x7c834cf4 [FRAME: ECallMethodFrame] [DEFAULT] R8 &lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#ffffff;FONT-FAMILY:Courier New;"&gt;&lt;strong&gt;System.Number.ParseDouble&lt;/strong&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#1000a0;FONT-FAMILY:Courier New;"&gt;(String,ValueClass System.Globalization.NumberStyles,Class System.Globalization.NumberFormatInfo)&lt;br /&gt;0x06ecec48 0x79a14e0f [DEFAULT] R8 &lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#ffffff;FONT-FAMILY:Courier New;"&gt;&lt;strong&gt;System.Double.Parse&lt;/strong&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#1000a0;FONT-FAMILY:Courier New;"&gt;(String,ValueClass System.Globalization.NumberStyles,Class System.IFormatProvider)&lt;br /&gt;0x06ecec84 0x79a0e3cc [DEFAULT] R8 &lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#ffffff;FONT-FAMILY:Courier New;"&gt;&lt;strong&gt;System.Convert.ToDouble&lt;/strong&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#1000a0;FONT-FAMILY:Courier New;"&gt;(String)&lt;br /&gt;0x06ecec88 0x06a30741 [DEFAULT] [hasThis] ValueClass System.Drawing.StringAlignment &lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#ffffff;FONT-FAMILY:Courier New;"&gt;&lt;strong&gt;C1.Util.Styles.StyleContext.1M&lt;/strong&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#1000a0;FONT-FAMILY:Courier New;"&gt;(String)&lt;br /&gt;0x06ececc4 0x06a306cd [DEFAULT] [hasThis] ValueClass System.Drawing.StringAlignment C1.Util.Styles.StyleContext.GetGeneralAlignment(Class C1.Util.Styles.Style,String)&lt;br /&gt;0x06ececd8 0x06a30246 [DEFAULT] [hasThis] Void C1.Util.Styles.StyleContext.UpdateStringFormat(Class C1.Util.Styles.Style,String)&lt;br /&gt;0x06ececf8 0x0580f464 [DEFAULT] [hasThis] ValueClass System.Drawing.SizeF C1.Util.Styles.StyleContext.GetContentSize(Class C1.Util.Styles.Style,Class System.Drawing.Graphics,ValueClass System.Drawing.SizeF,String,Class System.Drawing.Image)&lt;br /&gt;0x06eced40 0x06a31182 [DEFAULT] [hasThis] I4 C1.Util.Styles.StyleContext.GetContentWidth(Class C1.Util.Styles.Style,Class System.Drawing.Graphics,I4,String,Class System.Drawing.Image)&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;La información de la excepción se muestra en la siguiente caja, y es equivalente a la presentada en el stack manejado.&lt;/span&gt;&lt;/p&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:10pt;COLOR:#1000a0;FONT-FAMILY:Courier New;"&gt;Exception 0f69dff0 in MT 79bacb74: &lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#ffffff;FONT-FAMILY:Courier New;"&gt;&lt;strong&gt;System.FormatException&lt;/strong&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#1000a0;FONT-FAMILY:Courier New;"&gt;&lt;br /&gt;_message: Input string was not in a correct format.&lt;br /&gt;_stackTrace: &lt;br /&gt;00000000 &lt;br /&gt;00000000 &lt;br /&gt;79bbb998 &lt;br /&gt;79a14eb0 [DEFAULT] R8 &lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#ffffff;FONT-FAMILY:Courier New;"&gt;&lt;strong&gt;System.Double.Parse&lt;/strong&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#1000a0;FONT-FAMILY:Courier New;"&gt;(String,ValueClass System.Globalization.NumberStyles,Class System.IFormatProvider)&lt;br /&gt;06e8eca0 &lt;br /&gt;79bac7b0 &lt;br /&gt;79a0e3cb [DEFAULT] R8 &lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#ffffff;FONT-FAMILY:Courier New;"&gt;&lt;strong&gt;System.Convert.ToDouble&lt;/strong&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#1000a0;FONT-FAMILY:Courier New;"&gt;(String)&lt;br /&gt;06e8ed20 &lt;br /&gt;79bbf6b0 &lt;br /&gt;06a30740 [DEFAULT] [hasThis] ValueClass System.Drawing.StringAlignment &lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#ffffff;FONT-FAMILY:Courier New;"&gt;&lt;strong&gt;C1.Util.Styles.StyleContext.1M&lt;/strong&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#1000a0;FONT-FAMILY:Courier New;"&gt;(String)&lt;br /&gt;06e8ed24 &lt;br /&gt;0573bf28&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;¿Qué nos dice &lt;a href="http://www.aisto.com/roeder/dotnet/"&gt;Reflector&lt;/a&gt; del código en el método 1M?&lt;/p&gt;
&lt;table class="" style="WIDTH:100%;"&gt;

&lt;tr&gt;
&lt;td class=""&gt;&lt;img height="377" src="http://msmvps.com/blogs/pmackay/post16/16-04b.png" width="288" border="1" alt="" /&gt;&lt;/td&gt;
&lt;td class=""&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;No voy a entrar a analizar que hace o no el código.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Lo único que puedo vez rápidamente es que el desarrollador que codificó estas líneas tenia ganas de irse rápido a la casa, como muchas veces me pasó a mí &lt;img src="http://msmvps.com/emoticons/emotion-1.gif" alt="Smile" /&gt;.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;¿Por qué poner un try/catch en vez de hacer la validación que correspondería hacer?&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;¿Es tan difícil usar un expresión regular para validar decimales o &lt;em&gt;doubles&lt;/em&gt;, algo así como &amp;quot;&lt;strong&gt;[-+]?[0-9]*\.?[0-9]+&lt;/strong&gt;&amp;quot;?&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Muchas de los try/catch que son codificados podrían ser reemplazados por validaciones con &lt;em&gt;ifs&lt;/em&gt; y &lt;em&gt;elses&lt;/em&gt;, pero consume mucho más tiempo aprender cosas nuevas, y seguramente las pruebas en el computador del desarrollador no detectaron este problema &lt;img src="http://msmvps.com/emoticons/emotion-1.gif" alt="Smile" /&gt;.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Como no fue posible corregir el código defectuoso, ya que estaba en un componente de terceros, procedimos a hacer unos ajustes y remover parte de la funcionalidad que invocaba ese método. &lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Nueva prueba de carga&lt;/strong&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;El resultado obtenido habla por si solo. Consecuentemente, el grafico del uso de CPU ahora muestra un comportamiento más esperado para una prueba de carga. Y la gran cantidad de excepciones se fueron.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;img height="316" src="http://msmvps.com/blogs/pmackay/post16/16-03b.png" width="421" border="1" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Conclusión&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Tarde o temprano, los problemas aparecen. Es mejor invertir un par de horas en aprender algo que te podrá servir muchas veces a futuro, y dejar la chapucería para otro tipo de actividades.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Estas conclusiones están medias pobres, pero se debe a que no hay mucho más que decir. Los gráficos hablan por sí solos.&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Adicionales&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Si te interesa aprender de expresiones regulares, existe un muy buen libro y muchos sitios en internet. Personalmente uso el libro &lt;a href="http://www.amazon.com/Mastering-Regular-Expressions-Second-Jeffrey/dp/0596002890" target="_blank"&gt;Mastering Regular Expressions&lt;/a&gt;. &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Otros sitios web interesantes:&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;a href="http://www.regular-expressions.info/floatingpoint.html"&gt;http://www.regular-expressions.info/floatingpoint.html&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;a href="http://regexlib.com/default.aspx"&gt;http://regexlib.com/default.aspx&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Saludos,&lt;/span&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;br /&gt;Patrick.&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1041717" width="1" height="1"&gt;</description><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>¿Por qué no debo compilar en modo debug?, Parte III</title><link>http://msmvps.com/blogs/pmackay/archive/2007/07/12/post13.aspx</link><pubDate>Thu, 12 Jul 2007 04:38:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1016290</guid><dc:creator>pmackay</dc:creator><slash:comments>3</slash:comments><comments>http://msmvps.com/blogs/pmackay/archive/2007/07/12/post13.aspx#comments</comments><description>&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;font face="Calibri"&gt;&lt;span style="FONT-SIZE:12pt;BACKGROUND:green;COLOR:white;LINE-HEIGHT:115%;mso-themecolor:background1;mso-highlight:green;"&gt;Como&lt;/span&gt;&lt;font style="FONT-SIZE:12pt;" size="3"&gt; lo mencioné al terminar el segundo post sobre &lt;em&gt;por qué no debo habilitar debug=true en web.config&lt;/em&gt;, la tercera entrega vendría relacionada con optimizaciones a nivel de código IL.&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Si no leíste los posts anteriores, te recomiendo hacerlos, aunque este no es la continuación de ninguno de los dos. Las direcciones son:&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;a class="" href="http://msmvps.com/blogs/pmackay/archive/2007/05/08/post0c.aspx" target="_blank"&gt;http://msmvps.com/blogs/pmackay/archive/2007/05/08/post0c.aspx&lt;/a&gt;&lt;/span&gt; &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;a class="" href="http://msmvps.com/blogs/pmackay/archive/2007/05/23/post0e.aspx" target="_blank"&gt;http://msmvps.com/blogs/pmackay/archive/2007/05/23/post0e.aspx&lt;/a&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Bueno, veamos ahora las optimizaciones que se realizan, aunque siendo más ajustado a la realidad, el código generado en modo &lt;em&gt;debug&lt;/em&gt; está des-optimizado y con potenciales &amp;quot;bugs&amp;quot;. &lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Lo anterior significa que en modo &lt;em&gt;debug&lt;/em&gt;, se agregan operaciones a nivel de código de máquina, como también instrucciones de código a nivel de IL con el objetivo de apoyar el &lt;em&gt;debugging&lt;/em&gt; y la edición en caliente (&lt;em&gt;edit and continue)&lt;/em&gt;. Utilicé la palabra bugs entre comillas ya que no son bugs reales, pero en un escenario no adecuado, se comportan como tal.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Cuando se compila en modo &lt;em&gt;release&lt;/em&gt;, el código generado es de menor tamaño y mas rápido, es decir, optimizado, como esperaríamos que siempre fuese.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Para mi ejemplo, tomaré un problema causado por un ensamblado (&lt;em&gt;assembly&lt;/em&gt;) compilado en modo &lt;em&gt;debug&lt;/em&gt;, que es exactamente lo mismo que hace &lt;em&gt;debug=true&lt;/em&gt; en un sitio web, salvo que tienen ambientes de impacto diferentes.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Dejaremos para la cuarta y última entrega, el análisis de código de máquina.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Excepción lanzada&lt;/strong&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="FONT-SIZE:12pt;MARGIN:0cm 0cm 10pt;FONT-FAMILY:Calibri;"&gt;La aplicación web, en momentos de mucha carga, empezaba a lanzar excepciones del tipo &lt;em&gt;System.IndexOutOfRangeException&lt;/em&gt;, con el texto acorde &amp;quot;&lt;em&gt;Index was outside the bounds of the array,&lt;/em&gt;&amp;quot; estado del cual no lograba salir hasta un reinicio del proceso.&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;El siguiente era el &lt;em&gt;stack&lt;/em&gt; de ejecución al momento de lanzarse la excepción. Las direcciones de memoria son de un sistema de 64 bits.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&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;# Child-SP RetAddr : Args to Child : Call Site&lt;br /&gt;00 00000000`04c9dc50 00000000`7816c664 : ffffffff`fffffffe 00000000`04c9dd90 00000642`7fc2f008 00000001`7fffa790 : kernel32!PulseEvent+0x60&lt;br /&gt;01 00000000`04c9dd20 00000642`7f4477db : 00000642`7f330000 00000002`00000585 00000000`c089c2d8 00000642`7f4508eb : MSVCR80!CxxThrowException+0xc4&lt;br /&gt;02 00000000`04c9dd90 00000642`7fa0e4b2 : 00000000`04b833e0 00000000`06717520 00000642`7f521a48 00000000`00000003 : mscorwks+0x1177db&lt;br /&gt;03 00000000`04c9ddf0 00000642`782caee2 : 00000001`7fffa790 00000642`781043b8 00000642`802a24c0 00000000`00000000 : mscorwks!PreBindAssembly+0x428b2&lt;br /&gt;04 00000000`04c9df60 00000642`80261e22 : 00000642`7882fe08 00000000`c08982c0 00000001`7fffa790 00000000`c00f0a40 : &lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#ffffff;FONT-FAMILY:Courier New;"&gt;&lt;strong&gt;mscorlib_ni!System.Collections.ArrayList.Add&lt;/strong&gt;&lt;strong&gt;(System.Object)+0x32&lt;/strong&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#1000a0;FONT-FAMILY:Courier New;"&gt;&lt;br /&gt;05 00000000`04c9dfa0 00000642`80282dc9 : 00000000`c089be48 00000000`c08982c0 00000001`7fffa790 00000000`c00f0a40 : &lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#ffffff;FONT-FAMILY:Courier New;"&gt;&lt;strong&gt;ASSEMBLY.NAMESPACE.CLASE..ctor()+0x82&lt;/strong&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Por cierto, el nombre del ensamblado y la clase han sido modificados. No se llamaban &lt;em&gt;ASSEMBLY.NAMESPACE.CLASE&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;Analicemos el &lt;/strong&gt;&lt;em&gt;&lt;strong&gt;stack&lt;/strong&gt;&lt;/em&gt;&lt;strong&gt; de ejecución y la excepción&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;El constructor de CLASE, en la instrucción de offset 0x82 desde el inicio del método, estaba llamando al método &lt;em&gt;Add&lt;/em&gt; de un ArrayList.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;A su vez, el método &lt;em&gt;Add&lt;/em&gt;, en la instrucción de offset 0x32 desde el inicio del método, se estaba lanzando la excepción. &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;La excepción es de tipo &lt;em&gt;IndexOutOfRangeException&lt;/em&gt;, es decir, se está tratando de referenciar un ítem dentro de un arreglo, el cual no existe.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Código del cliente&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Revisando el código en el constructor (.ctor) de la clase CLASE, sorpresivamente no se encontró nada relacionado con &lt;em&gt;ArrayList&lt;/em&gt;. La clase CLASE es la clase proxy que se agrega a un proyecto, cuando se agrega la referencia de un servicio web . Con mayor razón, nadie ha tendría por qué agregar código ahí. &lt;em&gt;¿Entonces?&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;Reflector al rescate&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Volcando los ensamblados desde dentro del &lt;em&gt;dump&lt;/em&gt; y revisándolos con reflector, apareció este código:&lt;/span&gt;&lt;/p&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:10pt;COLOR:#1000a0;FONT-FAMILY:Courier New;"&gt;public CLASE() //Equivalente a .ctor&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#ffffff;FONT-FAMILY:Courier New;"&gt;&lt;strong&gt;__ENCList.Add(new WeakReference(this));&lt;/strong&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#1000a0;FONT-FAMILY:Courier New;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.Url = MySettings.Default.ASSEMBLY_NAMESPACE_&lt;span style="FONT-SIZE:10pt;COLOR:#1000a0;FONT-FAMILY:Courier New;"&gt;CLASE&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (this.IsLocalFileSystemWebService(this.Url))&lt;br /&gt;&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;this.UseDefaultCredentials = true;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.useDefaultCredentialsSetExplicitly = false;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&lt;br /&gt;&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;this.useDefaultCredentialsSetExplicitly = true;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;¿Y esa línea?... Interesante. &lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Necesitamos más pistas&lt;/strong&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Desensamblando &lt;em&gt;Add&lt;/em&gt; de &lt;em&gt;ArrayList&lt;/em&gt;, se obtiene el código de la siguiente sección, siendo la línea blanca la &amp;quot;responsable&amp;quot; del problema.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&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;public virtual int Add(object value)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (this._size == this._items.Length)&lt;br /&gt;&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;this.EnsureCapacity(this._size + 1);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#ffffff;FONT-FAMILY:Courier New;"&gt;&lt;strong&gt;this._items[this._size] = value;&lt;/strong&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#1000a0;FONT-FAMILY:Courier New;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this._version++;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return this._size++;&lt;br /&gt;}&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Ok, tenemos la línea responsable del error, que está en el código &lt;em&gt;Add&lt;/em&gt; de &lt;em&gt;ArrayList&lt;/em&gt;. Al evaluar el escenario posible, el error podía estar o generarse en cualquiera de todos estos puntos:&lt;/span&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Error en el código de Add&lt;/span&gt;&lt;/li&gt;
&lt;li style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Error en alguna otra parte del código, como CLASE..CTOR&lt;/li&gt;
&lt;li style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Algo más&lt;/li&gt;&lt;/ol&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;El punto número uno se descarta rápidamente, y el motivo es el siguiente. No es que el código Microsoft este libre de &lt;em&gt;bugs&lt;/em&gt;, sino que un error en &lt;em&gt;Add&lt;/em&gt; de &lt;em&gt;Arraylist&lt;/em&gt; habría sido reportado hace 346.432.194.385.037 años.&lt;img src="http://msmvps.com/emoticons/emotion-1.gif" alt="Smile" /&gt;.&lt;/p&gt;
&lt;p style="FONT-SIZE:10pt;FONT-FAMILY:Calibri;"&gt;Nota aparte: Leí en el libro de &lt;em&gt;Debugging&lt;/em&gt; de &lt;a href="http://www.microsoft.com/MSPress/books/8650.aspx"&gt;John Robbins&lt;/a&gt;, que si el &lt;em&gt;debugging&lt;/em&gt; corresponde a la eliminación de &lt;em&gt;bugs&lt;/em&gt;, el escribir código corresponde a la creación de &lt;em&gt;bugs.&lt;/em&gt; Esto lo podemos interpretar como &lt;em&gt;no hay código libre de errores&lt;/em&gt;.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;El método .ctor de CLASE presentaba esa línea de diferencia, la causante de todo el problema. &lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;¿Quién es __ENCList?.. más pistas por favor&lt;/strong&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Está definido como un &lt;em&gt;ArrayList&lt;/em&gt; estático, es miembro de CLASE, e instanciado en el siguiente método:&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&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;[&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#ffffff;FONT-FAMILY:Courier New;"&gt;&lt;strong&gt;DebuggerNonUserCode&lt;/strong&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#1000a0;FONT-FAMILY:Courier New;"&gt;]&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#ffffff;FONT-FAMILY:Courier New;"&gt;&lt;strong&gt;static&lt;/strong&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#1000a0;FONT-FAMILY:Courier New;"&gt; CLASE() //Equivalente a .cctor (sí, cctor con 2c)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;__ENCList = new ArrayList();&lt;br /&gt;}&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Interesante..un método estático, privado y decorado con un atributo de sospechoso nombre (&lt;em&gt;DebuggerNonUserCode&lt;/em&gt;), el cual reconozco que no conocía hasta ahora. Recomiendo su investigación. &lt;br /&gt;&lt;a class="" href="http://msdn2.microsoft.com/en-us/library/system.diagnostics.debuggernonusercodeattribute.aspx" target="_blank"&gt;http://msdn2.microsoft.com/en-us/library/system.diagnostics.debuggernonusercodeattribute.aspx&lt;/a&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Además, y algo muy importante cuando utilizas miembros estáticos, es la protección del acceso sobre éste. Que sean estáticos significa que es compartido por todos los &lt;em&gt;threads&lt;/em&gt; del proceso. Entonces, se debe cuidar que cuando se haga escritura sobre una variable estática, se haga garantizando que nadie más (otros &lt;em&gt;threads&lt;/em&gt;) pueda accederla mientras se realiza la operación. Esto es similar al uso de transacciones en algún motor de datos.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;En este caso, el miembro estático no está protegido, lo que en inglés se conoce como &lt;em&gt;thread-safe. &lt;/em&gt;El no cumplir con esto, puede llevarnos a situaciones de &lt;em&gt;race conditions&lt;/em&gt;. Más información en &lt;a class="" href="http://support.microsoft.com/kb/317723/en-us" target="_blank"&gt;http://support.microsoft.com/kb/317723/en-us&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;Recopilando pistas&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Tenemos las siguientes pistas:&lt;/span&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Error en código que no es del cliente &lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Código con error es agregado automáticamente por el compilador&lt;/span&gt;&lt;/li&gt;
&lt;li style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Clase estática con miembro estático que no está protegido&lt;/li&gt;
&lt;li style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Atributo de nombre sospechoso (debug)&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Las pistas anteriores no permiten concluir nada en específico, pero dan indicios y suposiciones de donde estaba el problema y qué se debía revisar.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Efectivamente el proyecto web asociado a esta aplicación estaba compilado en modo &lt;em&gt;debug&lt;/em&gt; (&lt;em&gt;debug=true&lt;/em&gt;), y tanto la variable &lt;em&gt;__ENCList&lt;/em&gt; como la línea en el constructor fueron agregadas por el compilador.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Habiendo realizado el cambio para compilar en modo release, y habiendo recompilado el proyecto, el problema no volvió a presentarse, y por supuesto, ni la variable ni la línea tampoco aparecieron en los ensamblados cargados en memoria.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Código de máquina&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;La revisión del código de máquina quedará para la cuarta y última entrega referente a esto.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;desde Santiago, Chile&lt;br /&gt;Patrick.&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1016290" width="1" height="1"&gt;</description><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>¿Microsoft y Van Halen?</title><link>http://msmvps.com/blogs/pmackay/archive/2007/07/06/post14.aspx</link><pubDate>Fri, 06 Jul 2007 19:20:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1005734</guid><dc:creator>pmackay</dc:creator><slash:comments>4</slash:comments><comments>http://msmvps.com/blogs/pmackay/archive/2007/07/06/post14.aspx#comments</comments><description>&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 12pt;"&gt;&lt;font face="Calibri"&gt;&lt;span style="FONT-SIZE:12pt;BACKGROUND:green;COLOR:white;LINE-HEIGHT:115%;mso-themecolor:background1;mso-highlight:green;"&gt;Siendo&lt;/span&gt;&lt;font style="FONT-SIZE:12pt;"&gt; un fanático de Van Halen, bueno, no tanto, pero me gusta mucho la música de ellos, en especial de la era Hagar, he estado revisando últimamente el sitio web para saber que ha pasado con la banda.&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="style2" style="FONT-SIZE:12pt;"&gt;&lt;span style="FONT-FAMILY:Calibri;"&gt;Además de los tradicionales problemas de drogas y de relación entre seres humanos, la última visita a &lt;a href="http://www.vanhalen.net/"&gt;www.vanhalen.net&lt;/a&gt; entregó este peculiar mensaje.&lt;/span&gt;&lt;/p&gt;
&lt;p class="style3" style="FONT-SIZE:12pt;TEXT-ALIGN:center;"&gt;&lt;em&gt;&lt;span class="style4"&gt;&lt;span style="FONT-FAMILY:Calibri;"&gt;&lt;span style="COLOR:#ff0000;"&gt;If you have registered for our newsletters in the past, please re-register your information, as &lt;strong&gt;Microsoft&lt;/strong&gt; has deleted our database. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 12pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Para los escépticos, pueden visitar el sitio y verlo por sus propios ojos, o ver la siguiente imagen capturada desde este.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 12pt;TEXT-ALIGN:center;"&gt;&lt;img height="814" src="http://msmvps.com/blogs/pmackay/post14/14-01b.png" width="466" alt="" /&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 12pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Que yo sepa, Microsoft no anda borrando bases de datos, ni menos de un grupo de música. A lo mejor no sé toda la historia.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;desde Santiago&lt;br /&gt;Patrick.&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1005734" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/pmackay/archive/tags/Windows+y+Microsoft/default.aspx">Windows y Microsoft</category></item><item><title>/3GB, memoria de kernel y un sábado de locos</title><link>http://msmvps.com/blogs/pmackay/archive/2007/06/24/post12.aspx</link><pubDate>Sun, 24 Jun 2007 20:02:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:985244</guid><dc:creator>pmackay</dc:creator><slash:comments>4</slash:comments><comments>http://msmvps.com/blogs/pmackay/archive/2007/06/24/post12.aspx#comments</comments><description>&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;font face="Calibri"&gt;&lt;span style="FONT-SIZE:12pt;BACKGROUND:green;COLOR:white;LINE-HEIGHT:115%;mso-themecolor:background1;mso-highlight:green;"&gt;Si&lt;/span&gt;&lt;font style="FONT-SIZE:12pt;" size="3"&gt; no considero las 3 horas que dormí del viernes al sábado, podría decir que llevo casi 48 horas despierto, o que llevaba hasta hoy en la mañana ya que pude dormir 5 horas más de 6 a 11 am (hoy es domingo en la tarde). ¿Cómo tanto?. La primera trasnochada fue por una fiesta de la oficina. La segunda, por un visita fugaz a un cliente en apuros. Mi día sábado fue extenuante y estresante para mi familia, cumpleaños, visitas, compra de pasajes, arreglo de taxis, reservas hoteleras, información adicional, ajustar otros viajes, una locura.&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Menos detalles aburridos y vamos al caso&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;El escenario era similar al descrito a continuación:&lt;/span&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Aplicaciones COM+ configuradas por defecto, salvo que algunas de ellas estaban configuradas con diferentes identidades (usuario que será utilizado para ejecutar la aplicación Com+). Las opciones disponibles para identidad son &lt;em&gt;Interactive&lt;/em&gt;, &lt;em&gt;Local Service&lt;/em&gt;, &lt;em&gt;Network Service&lt;/em&gt; o uno específico.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Después de un par de días funcionando, cualquier aplicación COM+ que no estuviese funcionando y era requerida, fallaría al levantarse&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Si la aplicación no había sido detenida durante todo el período de tiempo, seguiría funcionando sin problemas, aún cuando otras aplicaciones no pudiesen levantarse.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Si esta aplicación dejaba de ser requerida por más de 3 minutos (valor por defecto) y era bajada, un nuevo requerimiento trataría de levantarla y fallaría.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;font face="Calibri"&gt;&lt;font style="FONT-SIZE:12pt;" size="3"&gt;Claramente no estábamos en presencia de algún problema de código ya que&amp;nbsp; en ese caso, habría fallado siempre. Y más aún, nadie había hecho ningún cambio en los componentes en bastante tiempo. &lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Investigación del problema&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Como en cualquier actividad de resolución de problemas, lo PRIMERO que hay que mirar es el &lt;em&gt;event viewer&lt;/em&gt; o visor de sucesos (en español).&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Dos tipos de eventos llamaban la atención sutilmente. No habían muchos registros de ellos, pero estaban en el momento adecuado, en el lugar adecuado. &lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Uno de los eventos estaba en el mismo momento cuando empezaban los problemas. El mensaje era el siguiente.&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Failed to create a desktop due to desktop heap exhaustion&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Adicionalmente, otros tres eventos habían ocurrido uno de estos días, los que terminaron de aclarar la situación. Este evento el 2019:&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p class="MsoNormal" style="MARGIN:0cm 0cm 10pt;"&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Event ID 2019: “The server was unable to allocate from the system nonpaged pool because the pool was empty.”&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;Serie de preguntas y respuestas&lt;/strong&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;em&gt;Ingeniero, es decir, yo &lt;/em&gt;&lt;img src="http://msmvps.com/emoticons/emotion-1.gif" alt="Smile" /&gt;: ¿Configuraron /3GB en boot.ini?&lt;br /&gt;&lt;em&gt;Contraparte&lt;/em&gt;: Si&lt;br /&gt;&lt;em&gt;Ingeniero&lt;/em&gt;: ¿y configuraron &lt;em&gt;userva&lt;/em&gt;?&lt;br /&gt;&lt;em&gt;Contraparte&lt;/em&gt;: No&lt;br /&gt;&lt;em&gt;Ingeniero&lt;/em&gt;: mmm...interesante&lt;br /&gt;...&lt;br /&gt;&lt;em&gt;Ingeniero&lt;/em&gt;: ¿Cómo andan las PTEs?&lt;br /&gt;&lt;em&gt;Ingeniero&lt;/em&gt;: perfmon -&amp;gt; Memory -&amp;gt; Free System Page Table Entries (PTEs) --&amp;gt; cercano a 2.000 ... ouch&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Conclusión&lt;/strong&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;El Kernel se quedó sin memoria.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;¿Ahh?...bajémoslo a la tierra.&lt;/strong&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;En una arquitectura de 32 bits, la memoria virtual es un recurso medianamente escaso. No vamos a hablar de la cantidad memoria física del servidor. Si bien, mientras más memoria mejor, el problema a describir ahora no depende totalmente de la cantidad de memoria del servidor, ya que o bien tengas 2 o 20 GB, se presentará igual.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Con 32 bits, la memoria virtual, que tampoco tiene que ver con la memoria paginada en disco, está restringida a 4GB por aplicación. El valor 4GB se obtiene al elevar 2 a 32, o 2^32.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;De esos 4 GB virtuales, 2 GB son usados por un proceso y los otros 2 por el &lt;em&gt;kernel&lt;/em&gt;. Cada aplicación tendrá sus 2 GB virtuales y compartirán los 2 GB de &lt;em&gt;kernel&lt;/em&gt;. Debido a esto último, algunos de ustedes recordarán haber visto en &lt;em&gt;Task manager&lt;/em&gt; que un proceso nunca pasa de 1,7 o 1,8 GB. Bueno, la explicación es esa. Una aplicación no puede usar más de 2 GB de memoria virtual.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Existe un &lt;em&gt;switch&lt;/em&gt; para que sí lo haga, pero con su consecuencia. Este &lt;em&gt;switch&lt;/em&gt; se configura en el archivo boot.ini, y corresponde a la opción /3GB.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;El impacto de la aplicación de éste es que del espacio virtual de 4 GB, 1 GB pasa de memoria de &lt;em&gt;kernel&lt;/em&gt; a memoria de proceso de usuario. Entonces ahora un proceso de usuario puede llegar a usar 3 GB y el &lt;em&gt;kernel&lt;/em&gt; queda drásticamente reducido a 1 GB.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;SQL Server, Exchange, COM+ y los &lt;em&gt;Application pool&lt;/em&gt; de IIS son algunos de los procesos que tomarán ventaja de este cambio y podrán llegar a 2,7 u 2,8 GB de memoria usada, lo que representa un incremento del 50%, y que tiende a ayudar bastante en algunos casos, pero en otros, produce problemas si no se usa adecuadamente (como éste).&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;¿El problema?&lt;/strong&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;El kernel necesita memoria para poder funcionar, y 1 GB virtual no es suficiente en algunos casos. En el &lt;em&gt;kernel&lt;/em&gt; se cargan drivers, el manejador de memoria, de procesos, controladores gráficos, el HAL, manejo de &lt;em&gt;plug &amp;amp; play&lt;/em&gt; y otras tareas. &lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Además, el kernel maneja dos pool de memoria, uno llamado &lt;em&gt;paginable&lt;/em&gt; y el otros &lt;em&gt;no paginable&lt;/em&gt;. En ingles, &lt;em&gt;paged pool&lt;/em&gt; y &lt;em&gt;nonpaged pool&lt;/em&gt; respectivamente. ¿Recuerdan el evento 2019? Vuelvan a leer la descripción.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Al aplicar el &lt;em&gt;switch&lt;/em&gt; /3GB, el tamaño de estos pools se reduce a la mitad, pudiendo entonces en determinados casos agotarse y poner en riesgo el servidor. Si el &lt;em&gt;kernel&lt;/em&gt; no es capaz de obtener memoria de estos pools, varios problemas pueden ocurrir, a saber:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Problemas de interfaz grafica, en donde ésta no responde adecuadamente&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Problemas de funcionamiento de algunos procesos, para nuestro caso, las aplicaciones COM+ no levantan.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Falla en procesar requerimientos vía red&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Al aplicar /3GB se reduce también la cantidad de PTEs disponibles, lo que generará problemas con los requerimientos de IO, entre otros.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;strong&gt;Identidades de aplicaciones&lt;/strong&gt;&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Complementando lo anterior, si recuerdan, en un inicio hablamos de las identidades de las aplicaciones COM+.&lt;/p&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Este tópico no lo comprendo a cabalidad, pero puedo decir (con temor a equivocarme) que cada aplicación que es iniciada con un usuario diferente, requerirá que el sistema operativo cargue ciertos componentes para el usuario (desktop). Estos componentes incluyen:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Menús del sistema&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Ventanas&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Otra información.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Entonces, si tengo aplicaciones COM+ configuradas con X usuarios, podría llegar a cargar X desktops. ¿De donde se obtiene la memoria para cargar estos desktops? De la memoria del kernel.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Como sé que la información que acabo de entregar del tópico de Desktops es bastante limitada, prefiero incluir un link donde esta MUCHO mejor descrita. Aunque está en inglés, no está difícil. El link es &lt;a href="http://blogs.msdn.com/ntdebugging/archive/2007/01/04/desktop-heap-overview.aspx" target="_blank"&gt;http://blogs.msdn.com/ntdebugging/archive/2007/01/04/desktop-heap-overview.aspx&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;Solución&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Si tu aplicación no hará uso de 3GB, no incluyas la opción. No será necesaria.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Si tienes alguno de los servicios que mencioné antes y necesitas usarlo, deberás entonces usar además la opción &lt;em&gt;userva&lt;/em&gt; en el archivo &lt;em&gt;boot.ini&lt;/em&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Userva se utiliza para &amp;quot;mover&amp;quot; un poco de memoria de proceso de usuario a kernel. Realmente no mueve nada, pero el efecto final es que en vez de tener 3GB de usuario y 1GB de kernel, puedes configurar 2,7 GB y 1,3GB respectivamente, lo que ayudará a mitigar el problema, y en la gran mayoría de los casos, desaparecerá totalmente.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;El KB referenciado al final muestra como configurarlo. Si bien dice que se deberá probar entre 2900 y 3030, si es necesario para tu sistema, podrás llegar a un valor menor. Mayores valores no tienen sentido.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Si estas usando SQL Server, utiliza mejor AWE por sobre 3GB. No expondrás el kernel a estos problemas.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Adicionalmente, estos links te podrán proveer mas información:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;&lt;a href="http://technet.microsoft.com/en-us/library/7a44b064-8872-4edf-aac7-36b2a17f662a.aspx" target="_blank"&gt;http://technet.microsoft.com/en-us/library/7a44b064-8872-4edf-aac7-36b2a17f662a.aspx&lt;/a&gt; &lt;br /&gt;&lt;a href="http://support.microsoft.com/kb/316739" target="_blank"&gt;http://support.microsoft.com/kb/316739&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Este otro está curioso: &lt;a href="http://xentelworker.blogspot.com/2005/10/i-open-100-explorer-windows-and-my.html"&gt;http://xentelworker.blogspot.com/2005/10/i-open-100-explorer-windows-and-my.html&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Saludos,&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:Calibri;"&gt;Patrick.&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=985244" 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></channel></rss>