<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1376283136035918844</id><updated>2012-02-17T03:10:41.534+01:00</updated><category term='JDK/JVM'/><category term='JDBC/Oracle'/><category term='Netbeans'/><category term='General'/><category term='Java CAPS'/><category term='Java EE'/><category term='Criptografía/HSM'/><category term='Azul'/><category term='XML/SOAP'/><category term='Out-of-box'/><category term='NIO'/><category term='Sincronización'/><category term='Strings/Buffers/Ficheros'/><category term='GC'/><category term='Escape analysis'/><category term='JMS'/><category term='Benchmarks'/><category term='HTTP/S'/><category term='Apache'/><category term='GZIP'/><category term='Glassfish/Tomcat'/><category term='iPlanet'/><category term='Memoria'/><category term='Cloud computing'/><title type='text'>JAVA SERVER PERFORMANCE - Lo que un arquitecto de software sí puede hacer</title><subtitle type='html'>Reflexiones sobre problemas comunes de rendimiento y escalabilidad en tencologías Java EE, Java SE, SOA, AJAX, HTTPS...</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>72</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-703431394699879171</id><published>2011-11-30T17:45:00.002+01:00</published><updated>2011-11-30T17:51:01.773+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JDK/JVM'/><title type='text'>"HotRockit". La convergencia entre las JVMs Hotspot (Sun) y JRockit (Oracle-Bea)</title><content type='html'>Por fin se empiezan a ver los resultados de la cacareada convergencia entre las máquinas virtuales Hotspot y JRockit...&lt;br /&gt;&lt;br /&gt;Aunque de momento sólo tengamos poco más que el audio y las slides de la JavaOne 2011sobre las "líneas generales" de la convergencia:&lt;br /&gt;&lt;b&gt;&lt;a href="http://www.parleys.com/#st=5&amp;id=2654&amp;sl=0"&gt;What to Expect from HotRockit, by Marcus Hirt&lt;/a&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;¿Se acabó el espacio permanene "permgen"? ¿en serio? (sólo por este dolor de cabeza de Hotspot merece la pena la fusión :-)&lt;/li&gt;&lt;li&gt;¿"Flight Recorder" para viajar atrás en el tiempo y ver qué causó una incidencia?&lt;/li&gt;&lt;li&gt;...&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-703431394699879171?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/703431394699879171/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=703431394699879171' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/703431394699879171'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/703431394699879171'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2011/11/hotrockit-la-convergencia-entre-las.html' title='&quot;HotRockit&quot;. La convergencia entre las JVMs Hotspot (Sun) y JRockit (Oracle-Bea)'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-2660009794561134253</id><published>2011-05-31T12:56:00.003+02:00</published><updated>2011-05-31T13:00:30.750+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JDK/JVM'/><title type='text'>JRockit es ahora gratuíto</title><content type='html'>Pues eso. Más información, letra pequeña y q&amp;a en el blog de Henrik Stahl:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://blogs.oracle.com/henrik/entry/jrockit_is_now_free_and"&gt;JRockit is Now Free (and Other Java License Updates)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;:-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-2660009794561134253?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/2660009794561134253/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=2660009794561134253' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/2660009794561134253'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/2660009794561134253'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2011/05/jrockit-es-ahora-gratuito.html' title='JRockit es ahora gratuíto'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-5478168272295347596</id><published>2011-05-30T14:07:00.005+02:00</published><updated>2011-05-30T14:14:04.089+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java EE'/><title type='text'>Mucho cuidado con @Singleton</title><content type='html'>Me permito referenciar, como nota mental, el siguiente post de &lt;a href="http://www.adam-bien.com"&gt;Adam Bien&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.adam-bien.com/roller/abien/entry/singleton_the_perfect_cache_facade"&gt;@SINGLETON - THE PERFECT CACHE FACADE&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Donde avisa de:&lt;br /&gt;&lt;em&gt;&lt;blockquote&gt;&lt;strong&gt;@Singleton&lt;/strong&gt; in the default configuration is the perfect bottleneck (...) The annotation &lt;strong&gt;@ConcurrencyManagement(BEAN)&lt;/strong&gt; deactivates this limitation (...)&lt;/blockquote&gt;&lt;/em&gt;&lt;br /&gt;Para más información, ver el resto del post referenciado y el &lt;i&gt;see also&lt;/i&gt; que marca.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-5478168272295347596?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/5478168272295347596/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=5478168272295347596' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/5478168272295347596'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/5478168272295347596'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2011/05/mucho-cuidado-con-singleton.html' title='Mucho cuidado con @Singleton'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-8358466802256020247</id><published>2011-04-27T13:47:00.002+02:00</published><updated>2011-04-27T13:49:50.875+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Netbeans'/><title type='text'>Actualización del post "Tuning de NetBeans 7.x y 6.x"</title><content type='html'>Actualizado el post &lt;a href="http://serverperformance.blogspot.com/2008/10/rendimiento-del-netbeans6.html"&gt;Tuning de NetBeans 7.x y 6.x&lt;/a&gt;, al que incluso le he cambiado el nombre.&lt;br /&gt;&lt;br /&gt;Lo más importante (y lo dejo aquí para mi propio recuerdo):&lt;br /&gt;&lt;br /&gt;Mi fichero netbeans.conf contiene las siguientes opciones de lanzamiento:&lt;br /&gt;&lt;blockquote&gt;&lt;code&gt;&lt;i&gt;###[serverperformance.blogspot.com]&lt;/i&gt;&lt;br /&gt;netbeans_default_options="-J-Dcom.sun.aas.installRoot=\"C:\Java\glassfish-v2ur2\" -J-client -J-Xss2m -J-Xms32m -J-XX:PermSize=32m -J-XX:MaxPermSize=500m -J-XX:+UseConcMarkSweepGC -J-XX:+CMSClassUnloadingEnabled -J-XX:+CMSPermGenSweepingEnabled -J-Djava.index.useMemCache=true -J-Xverify:none -J-XX:+UseBiasedLocking -J-XX:+AggressiveOpts -J-Djava.net.preferIPv4Stack=true -J-Dsun.java2d.d3d=true -J-Dsun.java2d.noddraw=false -J-Dapple.laf.useScreenMenuBar=true -J-Dapple.awt.graphics.UseQuartz=true "&lt;br /&gt;&lt;/code&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-8358466802256020247?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/8358466802256020247/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=8358466802256020247' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/8358466802256020247'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/8358466802256020247'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2011/04/actualizacion-del-post-tuning-de.html' title='Actualización del post &quot;Tuning de NetBeans 7.x y 6.x&quot;'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-8453834617328689339</id><published>2011-04-24T23:13:00.006+02:00</published><updated>2011-04-25T00:37:08.955+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JDK/JVM'/><category scheme='http://www.blogger.com/atom/ns#' term='Netbeans'/><title type='text'>Tiered compilation en Hotspot 20 (Java 6u25)</title><content type='html'>&lt;div&gt;&lt;div&gt;Mientras seguimos esperando el cierre de versión de Java 7 (las listas de correo andan ardiendo estas últimas semanas, pero aún tardará), hace unos días salió &lt;a href="http://www.oracle.com/technetwork/java/javase/downloads/index-jsp-138363.html"&gt;Java 6 Update 25&lt;/a&gt;, donde por fin se incluye &lt;em&gt;Hotspot 20&lt;/em&gt;. Aparte de que está también recién horneado &lt;a href="http://netbeans.org/"&gt;Netbeans 7.0&lt;/a&gt; (yo llevaba tiempo trabajando con las release candidates)...&lt;br /&gt;&lt;br /&gt;A diferencia de los últimos updates, este sí promete mejoras de rendimiento, aunque la mala noticia es que el G1 (&lt;em&gt;Garbage First&lt;/em&gt;) continúa en modo experimental... pero la buena noticia es que parece que la tiered compilation por fin parece que funciona, ¿habrá llegado el esperado maná, lo mejor de los dos mundos (&lt;code&gt;-client&lt;/code&gt; y &lt;code&gt;-server&lt;/code&gt;) en uno&lt;br /&gt;&lt;br /&gt;Pego algunos extractos de las &lt;a href="http://www.oracle.com/technetwork/java/javase/6u25releasenotes-356444.html"&gt;releases notes&lt;/a&gt;:&lt;blockquote&gt;&lt;p&gt;&lt;em&gt;(...)&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;&lt;strong&gt;Java Hotspot VM 20&lt;br /&gt;&lt;/strong&gt;(...) contains improvements to performance, reliability and diagnostic information.&lt;br /&gt;&lt;br /&gt;A new feature in this version of HotSpot is "tiered" compilation in the Server VM that enables it to start quickly as does the Client VM, while achieving superior peak performance. This feature is enabled by specifying &lt;code&gt;-server&lt;/code&gt; and &lt;code&gt;-XX:+TieredCompilation&lt;/code&gt; command options.&lt;br /&gt;&lt;br /&gt;The Garbage First (G1) garbage collector continues to advance with Java SE 6u25, although it remains an experimental option.&lt;br /&gt;&lt;br /&gt;HotSpot diagnostic information has been expanded in several ways (...)&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Performance Improvement to BigDecimal&lt;/strong&gt;&lt;br /&gt;Improvements have been made to class BigDecimal enhancing its performance by thirty percent. BigDecimal is enabled by specifying &lt;code&gt;-XX:+AggressiveOpts&lt;/code&gt; command option.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Performance Improvement to java.util.logging.LogRecord&lt;/strong&gt;&lt;br /&gt;The performance of the class java.util.logging.LogRecord has been enhanced. This enhancement improves the efficiency of including source class and method names in java.util.logging log records.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;(...)&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;br /&gt;Y más información sobre "tiered compilation", por el ínclito Remí Forax, en &lt;a href="http://weblogs.java.net/blog/forax/archive/2010/09/05/tiered-compilation"&gt;http://weblogs.java.net/blog/forax/archive/2010/09/05/tiered-compilation&lt;/a&gt;, de donde me permito extraer:&lt;br /&gt;&lt;blockquote&gt;&lt;i&gt;"Tiered compilation in hotspot is an old dream. Hotspot has two JITs named c1 aka client JIT and c2 aka server JIT. The client JIT starts fast but provides less optimizations so it is used for GUI application. The server JIT starts more slowly but provide very good optimizations.&lt;br /&gt;The idea of tiered compilation is to get the best of both compilers, first JITs the code with c1 and then if the code is really hot to recompile it with c2."&lt;/i&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Obviamente en ejecuciones a largo plazo el "tiered compilation" no supone mejora general, pero sí durante los primeros minutos. He probado (como mera prueba) el arranque de Netbeans con &lt;code&gt;-server -XX:+TieredCompilation&lt;/code&gt; y el rendimiento se aproxima a -client (al menos es infinitamente mejor que con -server), aunque a cada cosa lo suyo, para aplicaciones gráficas y applets, seguirá siendo mejor el compilador cliente (por ahora, quizás algún día deje de existir la doble opción)&lt;br /&gt;&lt;br /&gt;Recopilando algunas de las últimas recomendaciones para aplicaciones servidor en arquitecturas de 64 bits que soporten NUMA, recomiendo probar estas opciones de arranque (con Java 6 u25 / Hotspot 20):&lt;br /&gt;&lt;br /&gt;&lt;code&gt;-server -XX:+TieredCompilation -XX:+UseCompressedOops -XX:+UseNUMA -XX:+UseParallelOldGC -Xverify:none -XX:+UseBiasedLocking -XX:+AggressiveOpts -Djava.net.preferIPv4Stack=true&lt;/code&gt; (aparte de los valores adecuados a cada caso para -Xms -Xmx -Xss -XX:PermSize -XX:MaxPermSize)&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-8453834617328689339?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/8453834617328689339/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=8453834617328689339' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/8453834617328689339'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/8453834617328689339'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2011/04/tiered-compilation-en-hotspot-20-java.html' title='Tiered compilation en Hotspot 20 (Java 6u25)'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-3788810519727465193</id><published>2011-02-08T22:17:00.006+01:00</published><updated>2011-02-08T22:33:31.202+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JDK/JVM'/><category scheme='http://www.blogger.com/atom/ns#' term='Memoria'/><title type='text'>-XX:+UseNUMA</title><content type='html'>Creo que desde Hotspot 17, al menos, está disponible esta opción (ahora vamos por Hotspot 19 con el JDK 1.6.0_23). Para mejorar el rendimiento de la recolección de basura en arquitecturas multicore, lo que según Sun-Oracle supone en total hasta una mejora de entre un 30 y un 40% en SPEC JBB 2005.&lt;br /&gt;&lt;br /&gt;¿Pero qué es NUMA? Pues ala, a verlo en la wikipedia: &lt;a href="http://es.wikipedia.org/wiki/NUMA"&gt;http://es.wikipedia.org/wiki/NUMA&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;En &lt;a href="http://download.oracle.com/javase/7/docs/technotes/guides/vm/performance-enhancements-7.html#numa"&gt;http://download.oracle.com/javase/7/docs/technotes/guides/vm/performance-enhancements-7.html#numa&lt;/a&gt; puede verse un resumen de la utilidad de esta opción en combinación con &lt;code&gt;-XX:+UseParallelGC&lt;/code&gt; (o &lt;code&gt;-XX:+UseParallelOldGC&lt;/code&gt;):&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;p&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;&lt;em&gt;NUMA Collector Enhancements &lt;/em&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;The Parallel Scavenger garbage collector has been extended to take advantage of the machines with NUMA (Non Uniform Memory Access) architecture. Most modern computers are based on NUMA architecture, in which it takes a different amount of time to access different parts of memory. Typically, every processor in the system has a local memory that provides low access latency and high bandwidth, and remote memory that is considerably slower to access.&lt;br /&gt;&lt;br /&gt;In the Java HotSpot Virtual Machine, the NUMA-aware allocator has been implemented to take advantage of such systems and provide automatic memory placement optimizations for Java applications. The allocator controls the eden space of the young generation of the heap, where most of the new objects are created. The allocator divides the space into regions each of which is placed in the memory of a specific node. The allocator relies on a hypothesis that a thread that allocates the object will be the most likely to use the object. To ensure the fastest access to the new object, the allocator places it in the region local to the allocating thread. The regions can be dynamically resized to reflect the allocation rate of the application threads running on different nodes. That makes it possible to increase performance even of single-threaded applications. In addition, "from" and "to" survivor spaces of the young generation, the old generation, and the permanent generation have page interleaving turned on for them. This ensures that all threads have equal access latencies to these spaces on average.&lt;br /&gt;&lt;br /&gt;The NUMA-aware allocator is available on the Solaris™ operating system starting in Solaris 9 12/02 and on the Linux operating system starting in Linux kernel 2.6.19 and glibc 2.6.1.&lt;br /&gt;&lt;br /&gt;The NUMA-aware allocator can be turned on with the &lt;code&gt;-XX:+UseNUMA&lt;/code&gt; flag in conjunction with the selection of the Parallel Scavenger garbage collector. The Parallel Scavenger garbage collector is the default for a server-class machine. The Parallel Scavenger garbage collector can also be turned on explicitly by specifying the &lt;code&gt;-XX:+UseParallelGC&lt;/code&gt; option.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;NUMA Performance Metrics &lt;/strong&gt;&lt;/span&gt;&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;When evaluated against the SPEC JBB 2005 benchmark on an 8-chip Opteron machine, NUMA-aware systems showed the following performance increases: &lt;/em&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;em&gt;32 bit – About 30 percent increase in performance with NUMA-aware allocator&lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;64 bit – About 40 percent increase in performance with NUMA-aware allocator&lt;/em&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;&lt;br /&gt;¡¡¡Lástima que con el kernel 2.6.18 (que es el de mis sistemas de producción) no se soporta!!!&lt;br /&gt;&lt;br /&gt;Sin haber hecho pruebas, estoy convencido en que en aplicaciones servidor (que efectivamente cumplen el patrón típico de toneladas de objetos creados y consumidos únicamente por el mismo thread) la ganancia será palpable en casi todos los escenarios, o cuando menos inocuo. Probablemente en algunas situaciones, sin embargo, sea peor el remedio que la enfermedad...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-3788810519727465193?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/3788810519727465193/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=3788810519727465193' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/3788810519727465193'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/3788810519727465193'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2011/02/xxusenuma.html' title='-XX:+UseNUMA'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-7070199699668198873</id><published>2010-08-27T16:21:00.008+02:00</published><updated>2010-08-27T16:39:59.930+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JDK/JVM'/><category scheme='http://www.blogger.com/atom/ns#' term='Azul'/><title type='text'>Azul Zing</title><content type='html'>&lt;div&gt;&amp;nbsp;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;a href="http://www.azulsystems.com/"&gt;&lt;img style="MARGIN: 0px 10px 10px 0px; WIDTH: 163px; FLOAT: left; HEIGHT: 39px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5510098808548579138" border="0" alt="" src="http://1.bp.blogspot.com/_4ZEuwiCuF6A/THfNrDDXV0I/AAAAAAAAALI/dxtlF7qfuM8/s400/azul_logo.png" /&gt;&lt;/a&gt;Me hago eco del último newsletter en &lt;a href="http://www.javaperformancetuning.com/"&gt;http://www.javaperformancetuning.com/&lt;/a&gt;, que la verdad parecía que esto iba a perder interés y ha entrado un nuevo jugador en el match de las JVM sobre arquitecturas x64... Azul Systems, que da el salto por fin y ha portado su &lt;a href="http://www.azulsystems.com/technology/zing-virtual-machine"&gt;Zing VM&lt;/a&gt; (anteriormente sólo disponible para su arquitectura sobre procesadores &lt;a href="http://www.azulsystems.com/technology/vega"&gt;Azul Vega&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.javaperformancetuning.com/news/news117.shtml"&gt;http://www.javaperformancetuning.com/news/news117.shtml&lt;/a&gt;&lt;br /&gt;&lt;em&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;em&gt;"Until now, if you wanted to eliminate all but the tiniest GC pauses (e.g. everything over 1 millisecond), you had to either program in a very non-object oriented way (almost eliminating object creation and destruction); or program in a specialized way to the Java Realtime System, or sometimes you would be lucky and the Oracle) JRockit Real Time or IBM WebSphere Real-time would work well on your app and keep the GC pauses right down there. &lt;/em&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;em&gt;But now &lt;a href="http://www.azulsystems.com/"&gt;Azul&lt;/a&gt; are providing a mainstream option that specifically targets keeping GC pauses tiny for the majority of Java applications, giving us all a new option with their new Zing product and the Managed Runtime Initiative. This is great news since with Oracle owning both JRockit and HotSpot, competitive&lt;br /&gt;pressures on JVM evolution were hugely reduced. And what competition Azul are providing: with GC pauses typically under 1 millisecond even for 100GBs heaps, and even the occasional longer GC pause still only into the 10-20 millisecond range! (Gil Tene, Azul's CTO, says as far as they can tell these longer GC pauses are caused by the OS context switching during a GC pause, and not because the GC pause actually takes any longer). &lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;(...)&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Previously, Azul was a very niche competitor - you had to buy their hardware if you wanted their low pause Java runtime, and typically that was only going to fly if you needed very large scaled JVMs. For the smaller low latency application that desperately wanted low pause GCs, Azul didn't even feature on the evaluation list. But now Azul has ported their runtime to run on &lt;/em&gt;&lt;a href="http://www.azulsystems.com/products/zing?quicktabs_29=4#quicktabs-29" target="_blank"&gt;&lt;em&gt;Intel and AMD processors&lt;/em&gt;&lt;/a&gt;&lt;em&gt;, suddenly this is an option for many more applications. And Azul haven't stopped there, they've also created the &lt;/em&gt;&lt;a href="http://www.managedruntime.org/" target="_blank"&gt;&lt;em&gt;Managed Runtime Initiative (MRI)&lt;/em&gt;&lt;/a&gt;&lt;em&gt; to provide a free JVM option with those incredibly low GC pauses. To enable this, they've contributed kernel changes to linux and implemented a Java Runtime based on openjdk - it's all available from the MRI site; and although currently it's only an alpha release, Azul are intending to stabilize the combination to a fully supported release. &lt;/em&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;em&gt;&lt;strong&gt;This is not only serious new competition for Oracle's JVM, but realistically targets two of the four top JVM performance challenges&lt;/strong&gt; (GC pause times and very large heaps; the other two are higher visibility into production runtimes; and transparently utilising multiple cores). Java long ago reached production maturity capable of handling almost anything thrown at it but, &lt;strong&gt;every time I think Java might be slowing down, yet another brilliant change happens in the Java space to make it yet better again&lt;/strong&gt;. Amazing that after 15 years on the leading edge, it just carries on staying right there."&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;/em&gt;&lt;br /&gt;&lt;p&gt;Recomiendo leer la newsletter íntegra Y SUSCRIBIRSE A LA MISMA, yo llevo ya unos añicos... :-)&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.javaperformancetuning.com/news/news117.shtml"&gt;http://www.javaperformancetuning.com/news/news117.shtml&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-7070199699668198873?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/7070199699668198873/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=7070199699668198873' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/7070199699668198873'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/7070199699668198873'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2010/08/azul-zing.html' title='Azul Zing'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_4ZEuwiCuF6A/THfNrDDXV0I/AAAAAAAAALI/dxtlF7qfuM8/s72-c/azul_logo.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-4324138619519166521</id><published>2009-04-24T18:27:00.001+02:00</published><updated>2009-04-24T18:27:00.182+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Cloud computing'/><category scheme='http://www.blogger.com/atom/ns#' term='General'/><title type='text'>Escalabilidad en cuanto a capacidad de poner en producción nuevas funcionalidades</title><content type='html'>Me ha resultado muy interesante este artículo del blog de uno de los fundadores de &lt;a href="http://friendfeed.com/"&gt;FriendFeed&lt;/a&gt; (y que anteriormente fue un mando intermedio en Google): &lt;a href="http://bret.appspot.com/entry/how-friendfeed-uses-mysql"&gt;http://bret.appspot.com/entry/how-friendfeed-uses-mysql&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Con una base de datos con decenas o cientos de millones de entradas, se encontraron un problema de escalabilidad entre otras cosas en la adición de nuevas funcionalidades, en concreto en el tiempo que cuesta añadir o quitar columnas a tablas, o añadir índices o eliminarlos. Estamos hablando de una o varias horas de "no disponibilidad de la BD" en un sistema supuestamente 24x7 :-)&lt;br /&gt;&lt;br /&gt;Así que la solución (no sólo para ese problema, sino también por estabilidad en los tiempos de respuesta, cosa que no termino de enteder por cierto) fue la que se describe en la mencionada entrada. Resumidamente, usar MySQL como motor de almacenamiento pero pasar como de la mierda de un modelo relacional...&lt;br /&gt;&lt;br /&gt;Enriquecedora lectura, aunque no me aplique... (que yo sepa ;-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-4324138619519166521?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/4324138619519166521/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=4324138619519166521' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/4324138619519166521'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/4324138619519166521'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2009/04/escalabilidad-en-cuanto-capacidad-de.html' title='Escalabilidad en cuanto a capacidad de poner en producción nuevas funcionalidades'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-6399601869137834972</id><published>2009-04-15T15:22:00.001+02:00</published><updated>2009-04-15T15:22:00.568+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JDK/JVM'/><title type='text'>Java 6u13</title><content type='html'>Desde hace 3 semanas, está disponible el update 13 de Java 6. Descargas aquí: &lt;a href="http://java.sun.com/javase/6/"&gt;http://java.sun.com/javase/6/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Recordemos que a partir del update 10, la política de versiones de Java SE es:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Las versiones pares incluyen mejoras y/o nuevas funcionalidades (además de parches de seguridad si aplican).&lt;/li&gt;&lt;li&gt;Mientras que las versiones impares están reservadas para contener exclusivamente (salvo excepciones).&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;En este caso, como puede verse en &lt;a href="http://java.sun.com/javase/6/webnotes/6u13.html"&gt;http://java.sun.com/javase/6/webnotes/6u13.html&lt;/a&gt;, se han corregido 7 vulnerabilidades y se ha aprovechado para corregir otros 7 bugs no relacionados directamente con la seguridad pero que se han considerado prioritarios.&lt;/p&gt;&lt;p&gt;Seguimos esperando ansiosos la inminente liberación del update 14 (Java 6u16), que supondrá un hito importante en cuanto a rendimiento (es decir incluirá todo lo experimentado en las &lt;em&gt;performance releases &lt;/em&gt;del año pasado y más cosas :-)&lt;/p&gt;&lt;p&gt;Y... La 6u14 &lt;strong&gt;ya va por la build b04&lt;/strong&gt;, lo que significa que estamos muy cerquita aunque este update yo creo que necesitará algunos más de lo habitual, seguramente será a mediados o finales en mayo cuando se libere, como llevamos tiempo precidiendo desde este blog. Más información y descargas de los snapshots: &lt;a href="http://download.java.net/jdk6/6u14/"&gt;http://download.java.net/jdk6/6u14/&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-6399601869137834972?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/6399601869137834972/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=6399601869137834972' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/6399601869137834972'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/6399601869137834972'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2009/04/java-6u13.html' title='Java 6u13'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-3978680281803379296</id><published>2009-04-08T22:52:00.000+02:00</published><updated>2009-04-08T22:52:00.552+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Escape analysis'/><category scheme='http://www.blogger.com/atom/ns#' term='Sincronización'/><category scheme='http://www.blogger.com/atom/ns#' term='Memoria'/><title type='text'>Incremento de un 100% de rendimiento de java.util.Logger (o los detalles sí importan)</title><content type='html'>Delicioso post de Jeremy Manson, que lleva tiempo teniéndnos "abandonaditos"...:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://jeremymanson.blogspot.com/2009/04/faster-logging-with-faster-logger.html"&gt;http://jeremymanson.blogspot.com/2009/04/faster-logging-with-faster-logger.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;A raíz de la necesidad de un cliente, que quería nada menos que un throughput de 2 MB por segundo en la escritura de logs (!), se han hemos una serie de optimizaciones en Logger.log para alcanzarlo, y se ha alcanzado...&lt;br /&gt;&lt;br /&gt;Los cambios ya están disponibles en el último build de &lt;a href="http://openjdk.java.net/"&gt;OpenJDK&lt;/a&gt;, y más detalles en &lt;a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6797480"&gt;http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6797480&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;El código de Jeremy es precioso en si mismo (lo siento, seguramente un no-programador no puede entender el adjetivo precioso aplicado a esto). Toda una clase de sincronización y volatilidad. Y es el mejor ejemplo de que el mejor "Escape analysis" sigue haciéndolo el ingeniero...&lt;br /&gt;&lt;br /&gt;Pero, y por mucho que él le quite culpas al desarrollador original de esa clase (incorporada en JDK 1.4)... joder ¿eso siempre ha estado ahí? ¿los procesos de entrega de Sun Microsystems no incluyen búsqueda de puntos calientes o locks adquiridos en cada thread?&lt;br /&gt;&lt;br /&gt;Lo cierto es que me ha dejado un sabor de boca muy muy agridulce...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-3978680281803379296?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/3978680281803379296/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=3978680281803379296' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/3978680281803379296'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/3978680281803379296'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2009/04/incremento-de-un-100-de-rendimiento-de.html' title='Incremento de un 100% de rendimiento de java.util.Logger (o los detalles sí importan)'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-5173630724943132822</id><published>2009-04-02T05:58:00.000+02:00</published><updated>2009-04-02T05:58:00.367+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Cloud computing'/><category scheme='http://www.blogger.com/atom/ns#' term='JDBC/Oracle'/><title type='text'>Deja de hibernar y despierta de una vez!</title><content type='html'>Me hago eco de este artículo: "&lt;a href="http://www.allthingsdistributed.com/2009/03/keeping_your_database_simple_and_fast.html"&gt;Good Advice on Keeping Your Database Simple and Fast&lt;/a&gt;".&lt;br /&gt;&lt;br /&gt;Independientemente de si nos parece bien, mal o regular todo lo demás, de si creemos en SimpleDB y S3 o no... e independientemente de si todo este rollo del Cloud mola pero no te aplica porque tus problemas son otros, tú trabajas en un sistema de información interno...&lt;br /&gt;&lt;br /&gt;...El primer párrafo del artículo es para enmarcarlo, y traduzco literalmente:&lt;br /&gt;&lt;blockquote&gt;&lt;em&gt;Mantener una base de datos simple y rápida es muchas veces complicado si se usan frameworks de alto nivel como (...) o tecnologías de persistencia de objetos en Java como HIBERNATE. Hay una gran cantidad de "magia" que ocurre fuera de tu vista sobre la que no tienes ningún control. Si tienes que escalar tu aplicación, generalmente son estas tecnologías para acceder a bases de datos relacionales las que se convierten en el cuello de botella tanto de rendimiento como de escalabilidad. (...)&lt;/em&gt;&lt;/blockquote&gt;&lt;br /&gt;¡Algo sensato! ¡Por fin! Por favor que vuelvan los tiempos del JDBC crudo (dentro o fuera de un EJB). Y no necesariamente implica perder el tiempo en codificar como un mulo.&lt;br /&gt;&lt;br /&gt;Ya en el año 2001 en mi anterior empresa ideé y lideré un sistema que llamamos "BeanBuilder" para generar todo tipo de código a partir del esquema de base de datos. Y no sólo me refiero a los EJB con altas/bajas/modificaciones/consultas/filtros/paginación, sino incluso llegamos a generar operativas completas con sus JSP de listado y de formularios de alta en base a plantillas. Para que sirvan como base para modificarlos, ampliarlos, etc. Pero siempre con control sobre el código generado porque generábamos código Java.&lt;br /&gt;&lt;br /&gt;Y allá por 2004 el sistema era realmente complejo, admitíamos tomar como punto de partida joins entre varias tablas y generar lo apropiado... Teníamos un formulario en el que elegías el tipo de framework que debía utilizar el código generado (¿EJB o framework propio con POJO? ¿JSP o XSLT? ¿Struts o nuestro framework propio?). Vamos, una herramienta para cualquier proyecto que abordáramos...&lt;br /&gt;&lt;br /&gt;Es decir si el objetivo es ahorrar esas horas de desarrollo "que no aportan valor" pero mantener el control sobre lo que potencialmente te va a dar problemas.&lt;br /&gt;&lt;br /&gt;No preguntéis el motivo, pero quedó en vía muerta. Si volviera a quella época hubiera lanzado un proyecto Open Source en toda regla...&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;¡Es hora de despertar de la "hibernación" en que estos arquitectos de salón nos han metido!&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_4ZEuwiCuF6A/SctewZHpdQI/AAAAAAAAAKk/P490smHFpkE/s1600-h/1168597964_g_0.jpg"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 255px; DISPLAY: block; HEIGHT: 320px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5317447970510697730" border="0" alt="" src="http://4.bp.blogspot.com/_4ZEuwiCuF6A/SctewZHpdQI/AAAAAAAAAKk/P490smHFpkE/s320/1168597964_g_0.jpg" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-5173630724943132822?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/5173630724943132822/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=5173630724943132822' title='3 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/5173630724943132822'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/5173630724943132822'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2009/04/deja-de-hibernar-y-despierta-de-una-vez.html' title='Deja de hibernar y despierta de una vez!'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_4ZEuwiCuF6A/SctewZHpdQI/AAAAAAAAAKk/P490smHFpkE/s72-c/1168597964_g_0.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-6084137123566690256</id><published>2009-03-25T01:15:00.002+01:00</published><updated>2009-03-26T11:15:17.077+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='General'/><title type='text'>Un medio, no un fin</title><content type='html'>Sin que sirva de precedente tiene poco que ver con el tema de este blog (o mucho si se piensa bien).&lt;br /&gt;&lt;br /&gt;Me ha llamado la atención el primer párrafo de un artículo sobre ENS (es de 2003, no digo que el estudio en si mismo sea interesante):&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;em&gt;"Ejecutivos y gerentes se esfuerzan por satisfacer las necesidades de los clientes y de los accionistas de manera simultánea"&lt;/em&gt;&lt;br /&gt;(&lt;a href="http://files.epsscentral.info/gery/pdfarticles/Enterprise%20Nervous%20System.pdf"&gt;http://files.epsscentral.info/gery/pdfarticles/Enterprise%20Nervous%20System.pdf&lt;/a&gt;)&lt;/blockquote&gt;Ahí está la madre del cordero. El arte de gestionarlo. Como me dijo un sabio (Zape) una vez: no te olvides de quién te paga el sueldo. O lo que es lo mismo, no olvidemos que las cosas las hacemos por un objetivo.&lt;br /&gt;&lt;br /&gt;Aunque para obtener ese objetivo como precio a pagar haya que satisfacer al cliente. Esta frase es de otro sabio, Zipi ;-)&lt;br /&gt;&lt;br /&gt;La tecnología al servicio del negocio. No al revés. Pero qué fácil es olvidarlo cuando no estás en primera línea...&lt;br /&gt;&lt;br /&gt;¡Qué gran pareja estos Zipi y Zape! Lástima que siguieran sus carreras musicales por separado...&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Y aplicado a la temática de este blog: el rendimiento y escalabilidad es un medio, no un fin.&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;:-/&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-6084137123566690256?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/6084137123566690256/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=6084137123566690256' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/6084137123566690256'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/6084137123566690256'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2009/03/un-medio-no-un-fin.html' title='Un medio, no un fin'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-2244926627583942309</id><published>2009-03-20T02:17:00.002+01:00</published><updated>2009-03-20T02:17:00.323+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Cloud computing'/><title type='text'>SaaS, IaaS y PaaS: Las tres clases de Cloud Computing</title><content type='html'>Lo único que está claro es que Cloud Computing es un palabro guay para poner en las PPT. Es como lo de la Web 2.0 o SOA, que nadie sabe lo que es pero todo el mundo habla de ella. Y en una reunión nadie pregunta qué es por miedo al ridículo.&lt;br /&gt;&lt;br /&gt;Esta es la única catalogación clara que hay por ahí en castellano, en Nubeblog:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.nubeblog.com/2008/10/15/saas-iaas-y-paas-las-tres-clases-de-cloud-computing/"&gt;http://www.nubeblog.com/2008/10/15/saas-iaas-y-paas-las-tres-clases-de-cloud-computing/&lt;/a&gt;&lt;br /&gt;Claro y conciso. De verdad.&lt;br /&gt;&lt;br /&gt;Yo tengo mi propia opinión y creo que hay modelos mixtos y valores añadidos muy diferenciados de un SaaS a otro, como para meterlos en el mismo saco. Pero para gustos los colores: del mismo modo que hay quien asegura que AJAX/RIA no es Web 2.0, hay quien asegura que SaaS no es Cloud, cuando para mi en realidad es el nivel más completo de CC: te doy un software y te lo evoluciono, en una infraestructura remota de la yo gestiono su crecimiento, gestión del centro de respaldo, procedimientos de paso a contingencia, help desk 24x7, y todos los servicios asociados... eso sí que es una nube :-)&lt;br /&gt;&lt;br /&gt;Otra cosa es que un SaaS pueda apoyarse (o no) en un IaaS y/o en un PaaS. Pero al cliente final se la debería traer floja...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-2244926627583942309?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/2244926627583942309/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=2244926627583942309' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/2244926627583942309'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/2244926627583942309'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2009/03/saas-iaas-y-paas-las-tres-clases-de.html' title='SaaS, IaaS y PaaS: Las tres clases de Cloud Computing'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-6654177902223039726</id><published>2009-03-13T12:35:00.000+01:00</published><updated>2009-03-13T12:35:00.935+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JDK/JVM'/><category scheme='http://www.blogger.com/atom/ns#' term='Memoria'/><title type='text'>Compressed pointers. Compressed oops.</title><content type='html'>Una de mis optimizaciones favoritas que aparecerán en la update 14 de Java 6 (actualmente en build 1, como os indiqué en un &lt;a href="http://serverperformance.blogspot.com/2009/02/java-6u12-production-y-java6u14-early.html"&gt;artículo anterior&lt;/a&gt;), y que ya estaba disponible en las "performance releases" es la &lt;strong&gt;compresión de punteros&lt;/strong&gt; en la máquina virtual de 64 bits.&lt;br /&gt;&lt;br /&gt;En Sun le llaman "compressed oops".&lt;br /&gt;&lt;br /&gt;El concepto es sencillo, y en realidad desde hace muuuuuucho lo tiene implementado JRockit, si los objetos mapeados es inferior de 4.000 millones de objetos (unos 32 gigas de RAM), se activa esta optimización, que reduciéndolo mucho puede explicarse de la siguiente manera: no es necesario que los punteros sean de 64 bits, pueden ser de de 32 bits, y hacer la resta con el punto de inicio de la memoria del S.O. utilizada. Esto es una reducción, en realidad es más complejo claro... Según el enlace que pongo abajo, literalmente: &lt;em&gt;"Compressed oops represent managed pointers (in many but not all places in the JVM) as 32-bit values which must be scaled by a factor of 8 and added to a 64-bit base address to find the object they refer to. This allows applications to address up to four billion objects (not bytes), or a heap size of up to about 32Gb. At the same time, data structure compactness is competitive with ILP32 mode."&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;Esto puede consiguir una mejora general del rendimiento de aproximadamente un 3%: Por un lado se consigue que todas las estructuras internas ocupen menos memoria (los punteros ocupan la mitad, y en algunos informes se habla de un consumo de hasta 1,5 veces mayor porque aquí hay mucho puntero aunque lo primero que nos dicen cuando aprendemos Java es que aquí no hay ni un solo puntero) y por otro lado se incrementa la capacidad de las cachés del servidor y of course por los buses puede trasitar el doble de información (en lo que a punteros se refiere) en el mismo tiempo.&lt;br /&gt;&lt;br /&gt;Obivamente el mapeo siempre hay que hacerlo y supone una penalización, pero la ganancia por el otro lado lo compensa con creces. Es decir, la máquina virtual de 64 bits será "casi" tan competitiva como la de 32 bits, no llegará a ser lo mismo pero la diferencia será inapreciable...&lt;br /&gt;&lt;br /&gt;Aunque algunos piensan que esta optimización sólo funciona si el heap máximo es inferior o igual a 4 GBytes (por aquello de los 32 bits), &lt;strong&gt;no es cierto&lt;/strong&gt;. Como digo arriba son 2^32 objetos referenciados por los punteros. Claro, si cada punterio apuntara a una estructura de 1 byte, esto sería 2 gigas, pero según las medias estadísticas de tamaño de objetos en heap, en la práctica supone aproximadamente 32 gigas efectivos teniendo en cuenta que esta optimización sólo afecta al código compilado no al interpretado, y en función del caso de uso esto es mucho mayor... vamos que la optimización afecta al 99% de los sistemas del mundo mundial.&lt;br /&gt;&lt;br /&gt;¿Te suena la frase de que las máquinas virtuales de 64 bits son más lentas o que consumen más memoria? Bien, pues ya no será una afirmación válida...&lt;br /&gt;&lt;br /&gt;Más información sobre compresión de punteros, el primer enlace es el clarificador:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://wikis.sun.com/display/HotSpotInternals/CompressedOops"&gt;http://wikis.sun.com/display/HotSpotInternals/CompressedOops&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://portal.acm.org/citation.cfm?id=1111587"&gt;http://portal.acm.org/citation.cfm?id=1111587&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://edocs.bea.com/jrockit/jrdocs/refman/optionXX.html"&gt;http://edocs.bea.com/jrockit/jrdocs/refman/optionXX.html&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-6654177902223039726?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/6654177902223039726/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=6654177902223039726' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/6654177902223039726'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/6654177902223039726'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2009/03/compressed-pointers-compressed-oops.html' title='Compressed pointers. Compressed oops.'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-959234809514680792</id><published>2009-03-06T13:34:00.008+01:00</published><updated>2009-03-06T14:15:15.446+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GC'/><category scheme='http://www.blogger.com/atom/ns#' term='Memoria'/><title type='text'>Los finalizers no son tus amigos (parte II)</title><content type='html'>Juro por la gloria de que James Gosling que ha sido casualidad... Al hilo de lo que comentábamos el lunes... &lt;em&gt;[Viene del artículo anterior: &lt;/em&gt;&lt;a href="http://serverperformance.blogspot.com/2009/03/los-finalizers-no-son-tus-amigos.html"&gt;&lt;em&gt;Los finalizers no son tus amigos&lt;/em&gt;&lt;/a&gt;&lt;em&gt;] &lt;/em&gt;&lt;br /&gt;&lt;br /&gt;Estoy suscrito a algunas listas de correo del desarrollo de JDK 7 y precisamente ayer jueves se recibía una notificación de un nuevo changeset que optimiza la gestión de PKCS#11 en el proveedor criptográfico del JDK, gracias a eliminar el método finalize() y cambiar su implementación por una weak reference. ¿Os suena???&lt;br /&gt;&lt;br /&gt;El webrev completo puede verse en: &lt;a href="http://hg.openjdk.java.net/jdk7/tl/jdk/rev/da9d0283a496"&gt;http://hg.openjdk.java.net/jdk7/tl/jdk/rev/da9d0283a496&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;La descripción es:&lt;br /&gt;&lt;blockquote&gt;&lt;em&gt;Issue: SSL stress test with GF leads to 32 bit max process size in less than 5 minutes with PCKS11 provider.&lt;br /&gt;Summary: Removed finalize() and add more error handling to native code.&lt;br /&gt;&lt;br /&gt;Author: valerie&lt;br /&gt;Reviewed-by: vinnie&lt;/em&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-959234809514680792?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/959234809514680792/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=959234809514680792' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/959234809514680792'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/959234809514680792'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2009/03/los-finalizers-no-son-tus-amigos-parte.html' title='Los finalizers no son tus amigos (parte II)'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-7636636214499401831</id><published>2009-03-02T21:41:00.002+01:00</published><updated>2009-03-06T13:43:16.523+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GC'/><category scheme='http://www.blogger.com/atom/ns#' term='Memoria'/><title type='text'>Los finalizers no son tus amigos</title><content type='html'>Gracias al artículo de este mes de javaspecialists.eu (&lt;a href="http://www.javaspecialists.eu/archive/Issue170.html"&gt;http://www.javaspecialists.eu/archive/Issue170.html&lt;/a&gt;), he redescubierto que hay que evitar la implementación del método finalize() siempre que sea posible.&lt;br /&gt;&lt;br /&gt;¿Por qué? Porque se añaden handlers a todas y cada una de las intancias de una clase que tenga ese método implementado. ¿Y qué? pues por un lado se añade más footprint de memoria a cada objeto, pero lo más importante: porque un objeto con finalizador es más costoso de alojar, y más costoso de eliminar: la VM añade un hook al objeto que causa que la instancia "sobreviva" a muchos de los pasos de la recolección de basura en lugar de ser retirado rápidamente, por lo que se promociona de forma prematura (y posiblemente innecesaria) dicha instancia a la zona de "old generation". Y esto a su vez hace que el old generation GC tenga más trabajo y se haga más lento y consuma más CPU. Según se apunta por ahí, esta situación puede mejorarse tuneando los ratios de tamaños, pero aún así el coste es importante.&lt;br /&gt;&lt;br /&gt;Pero... -te estarás diciendo- si yo necesito un finalizador para cerrar un stream!!! (o cualquier otro recurso). Bueno, puede que sí, puede que no. Revísalo ¿seguro? ¿o lo haces por comodidad? ¿o porque no te fías de que la VM haga lo que tiene que hacer? ¿o porque quieres ayudar al GC (y la cagas, como siempre)? :-)&lt;br /&gt;&lt;br /&gt;Si sigues estando seguro de que lo necesitas, dos comentarios: &lt;ol&gt;&lt;li&gt;Ok, pues no pasa nada. No he dicho que no uses finalizadores, sólo que los uses cuando sea absolutamente necesario. Ten en cuenta que este tip es de un nivel muy "fino". Si ese objeto no afecta al rendimiento global por no ser uno de los más utilizados ni entrar en hotspots, pues no te preocupes, recuerda la regla del 90-10.&lt;/li&gt;&lt;li&gt;Si necesitas tunear un caso concreto, y no has visto la forma de simpliciarlo reordenando otras partes del código, siempre puede reemplazarse un método finalize por un establecimiento de una referencia débil (weak) al objeto, y llamando explícitamente aun método equivalente que libera recursos cuando dicha referencia se establece a null.&lt;/li&gt;&lt;/ol&gt;Nota: esto es así siempre que el finalizador sea "no trivial" (entendiendo por trivial = vacío en tiempo de ejecución) es decir que si dejamos el método en nuestra clase pero su cuerpo está vacío, o si el optimizador del Hotspot mediante inlining lo vacía ("if (false) {...}"), lo dicho anteriormente no se considera: &lt;strong&gt;sólo se añaden hooks a objetos con finalizadores no triviales&lt;/strong&gt;.&lt;br /&gt;&lt;br /&gt;Más información: &lt;ul&gt;&lt;li&gt;&lt;a href="http://www.fasterj.com/articles/finalizer1.shtml"&gt;http://www.fasterj.com/articles/finalizer1.shtml&lt;/a&gt; y &lt;a href="http://www.fasterj.com/articles/finalizer2.shtml"&gt;http://www.fasterj.com/articles/finalizer2.shtml&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.javaperformancetuning.com/news/newtips083.shtml"&gt;http://www.javaperformancetuning.com/news/newtips083.shtml&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://java2go.blogspot.com/2007/09/javaone-2007-performance-tips-2-finish.html"&gt;http://java2go.blogspot.com/2007/09/javaone-2007-performance-tips-2-finish.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.petefreitag.com/articles/gctuning/"&gt;http://www.petefreitag.com/articles/gctuning/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.ibm.com/developerworks/java/library/j-jtp01274.html"&gt;http://www.ibm.com/developerworks/java/library/j-jtp01274.html&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_4ZEuwiCuF6A/SaumGLMXyiI/AAAAAAAAAKU/5P8CHkLkqno/s1600-h/Waffle-attack1.jpg"&gt;&lt;img style="MARGIN: 0px 10px 10px 0px; WIDTH: 200px; FLOAT: left; HEIGHT: 113px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5308519210800368162" border="0" alt="" src="http://1.bp.blogspot.com/_4ZEuwiCuF6A/SaumGLMXyiI/AAAAAAAAAKU/5P8CHkLkqno/s200/Waffle-attack1.jpg" /&gt;&lt;/a&gt;Ahora repite conmigo:&lt;br /&gt;Los finalizers no son mis amigos.... Finalizer malo, finalizer malo...&lt;br /&gt;&lt;br /&gt;&lt;em&gt;[Continúa en el siguiente post: &lt;/em&gt;&lt;a href="http://serverperformance.blogspot.com/2009/03/los-finalizers-no-son-tus-amigos-parte.html"&gt;&lt;em&gt;Los finalizers no son tus amigos (parte II)&lt;/em&gt;&lt;/a&gt;&lt;em&gt;]&lt;/em&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-7636636214499401831?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/7636636214499401831/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=7636636214499401831' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/7636636214499401831'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/7636636214499401831'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2009/03/los-finalizers-no-son-tus-amigos.html' title='Los finalizers no son tus amigos'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_4ZEuwiCuF6A/SaumGLMXyiI/AAAAAAAAAKU/5P8CHkLkqno/s72-c/Waffle-attack1.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-2193295876999571938</id><published>2009-02-24T15:01:00.008+01:00</published><updated>2009-03-02T13:05:30.324+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JDK/JVM'/><title type='text'>Java 6u12 (production) y Java6u14 (early access)</title><content type='html'>Pues como anuncié en el post &lt;a href="http://serverperformance.blogspot.com/2008/11/schedule-de-siguientes-updates-de-java.html"&gt;Schedule de siguientes updates de Java 6. Versiones de Hotspot y compatibilidad entre ellas&lt;/a&gt;, Sun se está ciñendo al calendario que me pasó mi contacto del equipo de Hotspot:&lt;br /&gt;&lt;br /&gt;Ya está disponible &lt;strong&gt;Java 6 update 12 &lt;/strong&gt;para descarga general y soporte para su uso en producción (&lt;a href="http://java.sun.com/javase/downloads/index.jsp"&gt;http://java.sun.com/javase/downloads/index.jsp&lt;/a&gt;):&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Las mejoras de rendimiento parecen únicamente ceñidas (una vez más!) al entorno cliente y gráfico.&lt;/li&gt;&lt;li&gt;No contiene corrección de ninguna vulnerabilidad de seguridad&lt;/li&gt;&lt;li&gt;La lista de bugs corregidos es importante, aunque los relativos a hotspot y a las bibliotecas core es muy reducida.&lt;/li&gt;&lt;li&gt;Soporte a Windows 2008 Server&lt;/li&gt;&lt;li&gt;[pero no incorpora Hotspot 12 sino que se mantiene Hotspot 11, supongo que han dejado en vía muerta las versiones 12 y 13]&lt;/li&gt;&lt;/ul&gt;Asimismo, lo que confirma a mi juicio la fecha estimada de mayo, podemos ya descargar &lt;strong&gt;Java 6 update 14 "Early Access"&lt;/strong&gt; desde &lt;a href="https://jdk6.dev.java.net/6uNea.html"&gt;https://jdk6.dev.java.net/6uNea.html&lt;/a&gt; y &lt;a href="http://download.java.net/jdk6/6u14/"&gt;http://download.java.net/jdk6/6u14/&lt;/a&gt;. &lt;br /&gt;&lt;ul&gt;&lt;li&gt;Esta versión incorpora la esperada V14 de Hotspot (que ya traía la fracasada versión &lt;a href="http://serverperformance.blogspot.com/2008/07/java-se-6u6p-performance-release.html"&gt;6u6p&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;Y el anunciadísimo colector de basura &lt;a href="http://research.sun.com/jtech/pubs/04-g1-paper-ismm.pdf"&gt;Garbage-First (G1)&lt;/a&gt;, que será el futuro recolector por defecto en entornos servidor aunque en este early access no está habilitado por defecto (ver instrucciones para hacerlo).&lt;/li&gt;&lt;li&gt;Todavía es el build 01, así que viendo la media de builds por versión, aún quedan tres :-)&lt;/li&gt;&lt;/ul&gt;Lo dicho, yo me espero a verano y migraré directamente de la u11 a la u14... lo cual no quita para que este comienzo de año sea emocionante desde el punto de vista de mejoras de rendimiento en Java, las cuales afortumadamente están aplicando a Java 6 y no sólo a la versión-que-algún-día-dejará-de-ser-beta Java 7.&lt;br /&gt;&lt;br /&gt;P.D: Los últimos builds del JDK 1.7 ya incorporan el Hotspot 15...&lt;br /&gt;&lt;br /&gt;:-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-2193295876999571938?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/2193295876999571938/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=2193295876999571938' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/2193295876999571938'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/2193295876999571938'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2009/02/java-6u12-production-y-java6u14-early.html' title='Java 6u12 (production) y Java6u14 (early access)'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-2480249023850941855</id><published>2009-02-10T19:32:00.003+01:00</published><updated>2009-02-19T22:10:25.797+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='General'/><title type='text'>Good bye Mr. Monson-Haefel</title><content type='html'>Hace tiempo que soy fan de &lt;strong&gt;&lt;a href="http://www.monson-haefel.com/"&gt;Richard Monson-Haefel&lt;/a&gt;&lt;/strong&gt;, que es el padre de muchas cosas, gurú de los EJB y del JMS y autor de varios libros de O'Reilly, de esos de tener en la cabecera de la cama.&lt;br /&gt;&lt;br /&gt;Creo que desde el año 2000 sigo sus artículos en JGuru, en The Server Side, en Java.net..., he vivido sus aportaciones en revisiones de las especificaciones de EJB y en procesos JSR/JCP, y su participación en Geronimo, OpenEJB y finalmente Groovy...&lt;br /&gt;&lt;br /&gt;En realidad viví de lejos su incursión en el mundo de plataformas RIA desde 2004 (me anclo en el pasado, hace ya 4 añitos que oficialmente dejó el mundo Java EE, aunque a seguido dando guerrilla desde entonces...), y ahora -aunque se veía venir- se ha pasado del todo al lado oscuro :-)&lt;br /&gt;&lt;br /&gt;Ha decidido reenfocar su carrera profesional desde finales de 2008 hacia el muldo &lt;a href="http://es.wikipedia.org/wiki/Multi-touch"&gt;Multitouch&lt;/a&gt;, digo que se ha pasado al otro lado porque es un gran fan de Microsft Surfaces :-)&lt;br /&gt;&lt;br /&gt;Valiente decisión para alguien que tenía a huevo aceptar uno de los múltiples y comodones puestos ejecutivos en grandes consultoras que le habían ofrecido, o dedicarse a ser conferenciante...&lt;br /&gt;&lt;br /&gt;Gracias por todo, Clever monkey. Seguiremos tus evoluciones en ese giro de 180 grados que has dado... así que este post es un pequeño y muy humilde homenaje, por mucho que no me hayas aceptado todavía como amigo en el Facebook ;-)&lt;br /&gt;&lt;br /&gt;Su blog, ahora reenfocado a la multitouch: &lt;a href="http://theclevermonkey.blogspot.com/"&gt;http://theclevermonkey.blogspot.com/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-2480249023850941855?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/2480249023850941855/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=2480249023850941855' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/2480249023850941855'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/2480249023850941855'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2009/02/good-bye-mr-monson-haefel.html' title='Good bye Mr. Monson-Haefel'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-5397284840942071385</id><published>2009-01-30T19:02:00.011+01:00</published><updated>2009-01-30T19:31:30.619+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java CAPS'/><category scheme='http://www.blogger.com/atom/ns#' term='Java EE'/><title type='text'>Balanceo de cargas de EJB en un clúster Java EE. "Collocation Optimization" y cómo afecta al diseño de procesamiento BATCH de alto rendimiento</title><content type='html'>&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Me gusta &lt;a href="http://java.sun.com/javaee/"&gt;Java EE&lt;/a&gt;. Y me gustan los &lt;a href="http://es.wikipedia.org/wiki/Enterprise_JavaBeans"&gt;EJB&lt;/a&gt;. Siempre en su justa medida, me explico y no me fustiguéis los amantes de &lt;a href="http://es.wikipedia.org/wiki/Spring_Framework"&gt;Spring Framework&lt;/a&gt;, que seguramente llevo más tiempo que vosotros en esto y las viejas costumbres son imposibles de cambiar...&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="FONT-WEIGHT: bold;font-size:130%;" class="Apple-style-span" &gt;To EJB or not to EJB&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;El concepto de componente empresarial (EJB) no es algo por lo que rasgarse las vestiduras, siempre que estemos hablando de &lt;a href="http://www.jguru.com/faq/view.jsp?EID=925"&gt;Stateless Session Beans&lt;/a&gt; o &lt;a href="http://www.jguru.com/faq/view.jsp?EID=327430"&gt;Message-Driven Beans&lt;/a&gt; y no de &lt;a href="http://www.jguru.com/faq/view.jsp?EID=917"&gt;Stateful Session Beans&lt;/a&gt;, o peor aún, de los infames &lt;a href="http://www.jguru.com/faq/view.jsp?EID=1075"&gt;Entity Beans&lt;/a&gt; (por muchas vueltas que le hubieran dado en la especificación 3.0 y lo que queda por dante con la 3.1 que se liberará este año...).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Lo de los Entity Beans es lo de siempre, mapeo O/R y por mucho que haya otras aproximaciones más potentes como Hibernate y similares, a mi lo que me gusta es tener el control. JDBC y SQL, tío. Que trabajar con SQL también es programar, y te aseguro que vas a tener menos problemas, la "magia" se termina pagando, en un proyecto es más el tiempo que se pierde en depurar las cosas raras de los mapeos O/R o conseguir optimizar una consulta o que haga un puto join de 8 tablas en lugar de 300 consultas a base de datos.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Pero me estoy yendo del asunto principal. Sigamos...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;La historia de Java EE no empieza en J2EE sino en JPE, allá por 1998 (sorpresa, su primer nombre no fue J2EE). Y antes de eso, en 1997 salió la especificación EJB 1.0 y Servlet 1.0 allá porfinales de 1997:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_4ZEuwiCuF6A/SYM6xv3nlZI/AAAAAAAAAJc/ltMEmZpS1xI/s1600-h/historia.png"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 400px; DISPLAY: block; HEIGHT: 232px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5297142213055583634" border="0" alt="" src="http://3.bp.blogspot.com/_4ZEuwiCuF6A/SYM6xv3nlZI/AAAAAAAAAJc/ltMEmZpS1xI/s400/historia.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Sí hay que agradecerle a Spring que haya conseguido poner las pilas a los chicos del &lt;a href="http://jcp.org/en/home/index"&gt;JCP&lt;/a&gt;, ya que la especificación 3.0 importó algunos de los conceptos de Spring Framework, en concreto lo que respecta al uso de Anotaciones para eliminar los deployment descriptors y simplificar el carajal de desarrollar y mantener un componente, que los servidores de aplicaciones inyecten código en tiempo de despliegue/ejecución. También, desde algo antes, la 2.1, se permite definir interfaz local además de (o en lugar de) la remota, por lo que en tiempo de ejecución cada vez el tema es también más ligero, amén de que los fabricantes de servidores de aplicaciones compatibles cada vez hacen las cosas un poquito mejor...&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;No quiero hacer un alegato a favor de Java EE o en contra de Spring. Basta con decir que Spring, igual que Struts o Hibernate son lo que son, y estamos en manos de un sólo proveedor (o una sola comunidad pero visto lo visto con JBoss o con el propio Spring, tarde o temprano la gente quiere llevar las judías a casa, lógico). Y Java EE es una especificación con múltiples implementaciones, y no está en manos de lo que a Sun le apetezca hacer con sus cosas, sino que son "estándares" (JSRs) del Java Community Process (JCP), que por mucho que esté liderado por Sun (faltaría plus) no es lo mismo, amigo...&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;Por cierto, aparte de todo el miedo que ha habido en 2008 con el cambio de política de licencia y releases de Spring (ver &lt;a href="http://www.cmaj.es/2008/09/26/springsource-cambia-la-politica-de-mantenimiento-de-spring/"&gt;artículo de Cmaj&lt;/a&gt;), también he oído voces que las nuevas versiones del susodicho cada vez son más complejas y pesadas. Oh, oh, ¿no era la comlejidad de Java EE y la simplicidad que deberían mantener las aplicaciones empresariales lo que hizo a Rod Johnson tirarse a crearlo allá por 2002?&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold;font-size:130%;" class="Apple-style-span" &gt;Qué aporta el Contenedor de EJB&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;El concepto de EJB está ya maduro, pues, y el servidor de aplicaciones / contenedor de EJB provee dos servicios/características fundamentales que los hace muy atractivos:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Demarcación transaccional. Pudiendo definir el comportamiento transaccional de cada método de negocio de forma declarativa mediante anotaciones. Vamos, para los de antes, el contenedor de EJBs actúa como MONITOR TRANSACCIONAL.&lt;/li&gt;&lt;li&gt;Distribución. La interfaz remota de un EJB es un punto de potencial separación en múltiples instancias o servidores de aplicaciones. Es decir, además de otros mecanismos en la capa de Contenedor HTTP / Motor de servlets, ahí tenemos un punto de potencial balanceo de cargas y failover. &lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_4ZEuwiCuF6A/SYM6x66nCzI/AAAAAAAAAJk/0xeV-8tjL3o/s1600-h/javaee.png"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 400px; DISPLAY: block; HEIGHT: 305px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5297142216020921138" border="0" alt="" src="http://4.bp.blogspot.com/_4ZEuwiCuF6A/SYM6x66nCzI/AAAAAAAAAJk/0xeV-8tjL3o/s400/javaee.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;En realidad es lo único que me gusta del modelo. Pero no es poco.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Como decía, como todo, las cosas con mesura. Las dos penúltimas arquitecturas que diseñe para clientes se basaban en un único EJB fachada de toda la lógica distribuida en POJOs normales (o unos pocos EJB, para no mentir). Granularidad muy gruesa, amigo. Me gustan las ventajas pero la sobrecarga excesiva.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="FONT-WEIGHT: bold;font-size:130%;" class="Apple-style-span" &gt;Balanceo de cargas y optimizaciones que dificultan las cosas&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Pero hay una trampa, siempre hay truco. El balanceo de cargas / failover que nos proporciona un clúster de servidores de aplicaciones a nivel de EJB no es tan automático como parece, sino que puede llevar alguna sorpresa.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Y esto es debido a que está clarito-clarito que la arquitectura Java EE está pensado en el mundo online, orientado a peticiones remotas (de un navegador o de una aplicación remota) que requieren un procesamiento extrarápido y extraescalable. Lo cual hace que por defecto los servidores de aplicaciones se pasen por el forro de los cojones la distribución de cargas entre invocaciones de EJB. Es decir, si ya hemos balanceado en la capa http / servlet, ¿para qué volver a perder el tiempo en balancear la ejecución de cada componente involucrado en esa operativa si se da la premisa de que la sobrecarga de cada invocación remota (calcular_round-robin-&gt;serializar-&gt;enviar_por_la_red-&gt;deserializar-&gt;ejecutar-&gt;serializar-&gt;respuesta_por_la_red-&gt;deserializar) seguramente es más costosa que los milisegundos de ejecución de ese método de negocio?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Pues mejor no hacerlo. Y así es cómo actúan casi todos los servidores de aplicaciones cuando están en Clúster. al menos Weblogic, Glassfish y Websphere. E infiero que también el resto: si se invoca a un EJB desde dentro de un servidor de aplicaciones que está en clúster, el servidor de aplicaciones SIEMPRE invocará una instancia local del componente (que está desplegado en esa isntancia) y nunca a una de otro nodo del clúster. Es lo que se llama "optimización por colocación" que no es exactamente lo mismo que "afinidad de servidor".&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A modo de ejemplo, pego un extracto de la documentación de Weblogic 10, que tiene su toque de ironía por cierto:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;span style="FONT-STYLE: italic" class="Apple-style-span"&gt;&lt;p class="pBody"&gt;&lt;a href="http://download.oracle.com/docs/cd/E11035_01/wls100/cluster/load_balancing.html"&gt;http://download.oracle.com/docs/cd/E11035_01/wls100/cluster/load_balancing.html&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class="pBody"&gt;WebLogic Server always uses the local, collocated copy of Object A, rather than distributing the client’s calls to other replicas of Object A in the cluster. It is more efficient to use the local copy, because doing so avoids the network overhead of establishing peer connections to other servers in the cluster.&lt;br /&gt;&lt;/p&gt;&lt;p class="pBody"&gt;&lt;a name="wp1024887"&gt;&lt;/a&gt;This optimization is often overlooked when planning WebLogic Server clusters. The collocation optimization is also frequently confusing for administrators or developers who expect or require load balancing on each method call. If your Web application is deployed to a single cluster, the collocation optimization overrides any load balancing logic inherent in the replica-aware stub. &lt;/p&gt;&lt;p class="pBody"&gt;&lt;a name="wp1024890"&gt;&lt;/a&gt;If you require load balancing on each method call to a clustered object, see &lt;a href="http://download.oracle.com/docs/cd/E11035_01/wls100/cluster/planning.html#wp1115757"&gt;Recommended Multi-Tier Architecture&lt;/a&gt; for information about how to plan your WebLogic Server cluster accordingly. &lt;/p&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span style="FONT-STYLE: italic" class="Apple-style-span"&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;span style="FONT-WEIGHT: bold" class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="FONT-WEIGHT: bold" class="Apple-style-span"&gt;&lt;span style="FONT-WEIGHT: normal" class="Apple-style-span"&gt;&lt;div&gt;Y, todo esto, son conclusiones para generalizar el comportamiento de los servidoresd e aplicaciones líderes del mercado, pero podría no ser así con el servidor de aplicaciones que hayas elegido... &lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold" class="Apple-style-span"&gt;&lt;span class="Apple-style-span"  style="font-size:130%;"&gt;Pero... ¿y la especificación EJB / Java EE no deja clarito estos comportamientos?&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Pues lamentablemente no, curiosamente la especificación no dice absolutamente nada de cómo debe comportarse un clúster de servidores de aplicaciones. Bueno, miento, en realidad lo dan por sentado: los "contratos" que establece la especificación que deben cumplir los fabricantes de servidores de aplicaciones indican cómo debe esperar un diseñador/desarrollador que se comporte su aplicación y sus componentes. Pero en el alto nivel, nada de balanceo. Volvemos a lo mismo que decía antes con la magia del mapeo O/R o con las implicaciones del RMI/IIOP o con las curiosidades del protocolo HTTP: los pollos de las especificaciones piensan que un "desarrollador" no debe preocuparse por esas cosas. Pues mira por dónde, yo digo que sí.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Y también hay "zonas muertas" como si el EJB Timer Service debe disparar un trigger sólo en una instancia del clúster o en todas ellas (esto lo digo como curiosidad)...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;En cualquier caso, créeme, lo que cuento arriba no es sólo válido para Weblogic, también para el resto, me juego una caña.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="FONT-WEIGHT: bold" class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="FONT-WEIGHT: bold;font-size:130%;" class="Apple-style-span" &gt;Procesamiento por lotes (en batch) de enormes volúmenes de datos&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;Leches, os diréis, ¿y esta chuminada en qué me afecta a mi? Si parece que es lo correcto ¿no? &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Sí, en el 90% de los casos. Es decir, como digo en un procesamiento online normal así es. Pero ¿y qué hay de un peazo de proceso batch para tratar en chuncks millones de registros o hacer procesamientos computacionalmente complejos? ¿cómo beneficiarnos de las N máquinas del clúster en este tipo de procesamiento?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Pues, salvo que utilicemos aproximaciones menos transparentes (que desaconsejo), la única forma de hacerlo es que la clase que invoca al EJB esté fuera del clúster, en otro servidor de aplicaciones, o clúster administrativo separado.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Incluso en este caso, hay que tener cuidado porque en la misma URL de Weblogic que referencio, hablan de la "Transactional Collocation", es decir dentro de una misma transacción, si se invoca a métodos de negocio del mismo EJB aunque nos hayamos asegurado de que sea remoto... el muy cabrito invoca siempre a la misma instancia del clúster elegida en el round-robin para la primera invocación.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;O sea, que la única forma de balanceo real y efectiva es que cada invocación a EJB esté en una transacción distinta (o que el método esté demarcado como REQUIRESNEW). Para un procesamiento batch basado en tratamientos de lotes (o chuncks) de información, esto nos sirve. Es decir, tenemos que procesar 20.000.000 de filas, y -por si lo estábais pensando- es una gilipollez intentar hacerlo en una sola transacción, de modo que la estrategia más ampliamente utilizada es hacerlo en "pequeñas" transacciones, cada una de ellas procesando por ejemplo 10.000 registros. Bien, en este escenario es perfectamente viable puesto que los requerimientos "de negocio" casualmente coinciden con las capacidades del clústering descrito. Siempre que el "master" o "controller" del proceso batch esté fuera del clúster donde se ejecutan los componentes de tratamiento de cada lote.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Últimamente me he hecho experto en procesamiento batch en Java EE. Que por cierto es casi un mundo virgen, qué curioso. Salvo por &lt;a href="http://www.opensymphony.com/quartz/"&gt;Quartz&lt;/a&gt; como único planificador medianamente serio (ejem si lo comparamos con &lt;a href="http://www-01.ibm.com/software/tivoli/products/scheduler/"&gt;TWS&lt;/a&gt;, anda que no nos queda...), y &lt;a href="http://static.springframework.org/spring-batch/"&gt;Spring Batch&lt;/a&gt; como único intento de framework para batches de alto rendimiento (aunque no lo recomiendo, sinceramente, aparte de que está muy-muy verde, tiene toda la pinta de que evoluciona hacia el Spring Integrator) con perdón del fantástico artículo &lt;a href="http://www.devx.com/Java/Article/20791/0/page/1"&gt;High-volume Transaction Processing in J2EE&lt;/a&gt;, cuyas bases son impecables pero si tenemos cuidado con la paja mental que acabo de soltar y cuyo framework planteado pego a continuación:&lt;br /&gt;&lt;/div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://assets.devx.com/articlefigs/9823.png"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 455px; DISPLAY: block; HEIGHT: 367px; CURSOR: hand" border="0" alt="" src="http://assets.devx.com/articlefigs/9823.png" /&gt;&lt;/a&gt; &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Aunque, ya que estamos, si de verdad estamos hablando de procesamiento batch de eTL de grandes volúmenes de información, dejémosnos de Java EE y vayamos al siguiente nivel de abstracción, los Servidores de Integración (como Java CAPS, que incorpora un bonito módulo de eTL) o herramientas de eTL independientes. Aunque por cierto, en el caso de Java CAPS sospecho que el procesamiento "distribuido" de esas Collaborations de transformación no es tan distribuido, al fin y al cabo una Colaboración se implementa por debajo como un EJB, así que...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="FONT-WEIGHT: bold" class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="FONT-WEIGHT: bold;font-size:130%;" class="Apple-style-span" &gt;¿Y todo esto me afecta para algo o no?&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Pues tú sabrás, tú eres el arquitecto :-)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;En el 90% de las situaciones no, estáte tranquilo. Tú o tus compañeros de Sistemas Medios han diseñado seguro-seguro una arquitectura que balancea a nivel de motor de servlets, o mejor aún, pode delante de él, con balanceadors de cargas delante de los Apaches para las peticiones de los navegadores.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Pero en situaciones "no tan online" o en las que tu sistema hace procesamiento "de verdad" (y no las puñeteras aplicaciones de gestión que en realidad son las bancas online, comercios electrónicos y otras cosas que nos creemos que son muy avanzadas). O si tienes que precalcular informes estadísticos del último mes, o generar ficheros de extractos para ser descargados por todos tus clientes al día siguiente, no pretenderás hacerlo online ¿verdad? Y aunque la respuesta sea "sí", probablemente te gustaría no infrautilizar los flamantes N servidores que te han puesto ahí y cuyo balanceo "por delante" presupone que hay una homogeneidad en la duración y recursos consumidos por cada operativa o transacción...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;También es cierto, que un buen particionamiento de los chunks es la base de un buen proceso batch, y que sólo son paralelizables tareas en las que hay más carga de CPU de tu servidor que de la base de datos que tienes por detrás. Porque como sea ese último caso, ya puedes paralelizar en Java, que el problema no lo tienes ahí... :-)&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Pero el rollo de los particionamientos, chunks y otras aves sería motivo de otro artículo bien gordote... (para una introducción, lee el enlace que he referencio arriba, lo pego otra vez: &lt;a href="http://www.devx.com/Java/Article/20791/0/page/1"&gt;http://www.devx.com/Java/Article/20791/0/page/1&lt;/a&gt; )&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;P.D: Cada vez me cuesta más encontrar tiempo y fuerzas para escribir...&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-5397284840942071385?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/5397284840942071385/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=5397284840942071385' title='10 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/5397284840942071385'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/5397284840942071385'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2009/01/balanceo-de-cargas-de-ejb-en-un-cluster.html' title='Balanceo de cargas de EJB en un clúster Java EE. &quot;Collocation Optimization&quot; y cómo afecta al diseño de procesamiento BATCH de alto rendimiento'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_4ZEuwiCuF6A/SYM6xv3nlZI/AAAAAAAAAJc/ltMEmZpS1xI/s72-c/historia.png' height='72' width='72'/><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-4835468966282646849</id><published>2009-01-02T00:43:00.000+01:00</published><updated>2009-01-02T00:43:05.193+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JDK/JVM'/><title type='text'>Historia de versiones del JDK y conceptos de rendimiento en Java</title><content type='html'>Esta vez simplemente apunto unos enlaces a la Wikipedia.&lt;br /&gt;&lt;br /&gt;Son muy-muy buenas recopilaciones aunque la entrada sobre "Java performance" está algo desactualizada y algunas de las optiomizaciones que marca como "futuras" ya están disponibles en Java 6u10 (y otras fueron introducidas en la 6u6-p.&lt;br /&gt;&lt;br /&gt;Y no sólo son buenas referencias por su contenido en si mismo, sino porque la bibliografía a la que asimismo referencian es tremenda. Enhorabuena a sus autores:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Java_version_history"&gt;http://en.wikipedia.org/wiki/Java_version_history&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Java_performance"&gt;http://en.wikipedia.org/wiki/Java_performance&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-4835468966282646849?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/4835468966282646849/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=4835468966282646849' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/4835468966282646849'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/4835468966282646849'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2009/01/historia-de-versiones-del-jdk-y.html' title='Historia de versiones del JDK y conceptos de rendimiento en Java'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-697550999469226612</id><published>2008-12-26T11:24:00.000+01:00</published><updated>2008-12-26T11:24:00.166+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='HTTP/S'/><category scheme='http://www.blogger.com/atom/ns#' term='General'/><title type='text'>YSlow</title><content type='html'>&lt;p&gt;&lt;a href="http://developer.yahoo.com/yslow/"&gt;http://developer.yahoo.com/yslow/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Complemento para Firebug que analiza las página según &lt;a href="http://developer.yahoo.com/performance/rules.html"&gt;las best practices de rendimiento de sitios web&lt;/a&gt; del equipo Exceptional Performance de Yahoo.&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-697550999469226612?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/697550999469226612/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=697550999469226612' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/697550999469226612'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/697550999469226612'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/12/yslow.html' title='YSlow'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-5170531794645840183</id><published>2008-12-19T04:07:00.000+01:00</published><updated>2008-12-19T04:07:00.537+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='HTTP/S'/><category scheme='http://www.blogger.com/atom/ns#' term='General'/><title type='text'>webpagetest.org</title><content type='html'>Me hago eco de esta reseña de la herramienta &lt;a href="http://www.webpagetest.org/"&gt;http://www.webpagetest.org/&lt;/a&gt; que Martín hace en su blog.&lt;br /&gt;&lt;br /&gt;No la he probado pero tiene muy buena pinta. Ahí está el artículo: &lt;a href="http://brigomp.blogspot.com/2008/12/probando-el-rendimiento-de-pginas-web.html"&gt;http://brigomp.blogspot.com/2008/12/probando-el-rendimiento-de-pginas-web.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-5170531794645840183?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/5170531794645840183/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=5170531794645840183' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/5170531794645840183'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/5170531794645840183'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/12/webpagetestorg.html' title='webpagetest.org'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-5232544369684607533</id><published>2008-12-14T10:44:00.001+01:00</published><updated>2008-12-14T10:44:01.266+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='General'/><title type='text'>highscalability.com</title><content type='html'>Gracias a este &lt;a href="http://brigomp.blogspot.com/2008/12/escala-java-entrevista-todd-hoff.html"&gt;post&lt;/a&gt; en el blog de Pensamientos Ágiles he descubierto uno de los mejores blogs/sites relacionados con la escalabilidad y cloud computing:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://highscalability.com/"&gt;http://highscalability.com/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Artículos muy buenos y los enlaces también. Por cierto, muy chula la serie de artículos &lt;a href="http://highscalability.com/links/weblink/24"&gt;"Real Life Architectures"&lt;/a&gt;, con notas acerca de la arquitectura de Amazon, Google, Flickr, Twitter, YouTube, eBay, Digg, MySpace...&lt;br /&gt;&lt;br /&gt;P.D: Ya estoy viendo a mi amigo &lt;a href="http://www.cmaj.es/"&gt;cmaJ&lt;/a&gt; haciendo palmas con las orejas por poder cotillear sobre estos grandes... ;-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-5232544369684607533?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/5232544369684607533/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=5232544369684607533' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/5232544369684607533'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/5232544369684607533'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/12/highscalabilitycom.html' title='highscalability.com'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-7092112629987147138</id><published>2008-12-09T21:20:00.002+01:00</published><updated>2009-04-17T11:19:49.485+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='iPlanet'/><category scheme='http://www.blogger.com/atom/ns#' term='HTTP/S'/><category scheme='http://www.blogger.com/atom/ns#' term='Apache'/><title type='text'>Eliminar ETags para incrementar el rendimiento</title><content type='html'>Esto es algo que sigo sin entender, y que encima está por defecto en Apache: si para comprobar que es correcta la versión de un contenido que el navegador tiene cacheada se envía la cabecera "If-Modified-Since"... ¿por qué además existen los headers &lt;a href="http://en.wikipedia.org/wiki/HTTP_ETag"&gt;ETag&lt;/a&gt; en respuestas y posteriores If-None-Match en peticiones? (Nota para despistados: el ETag es como una especie de digest cutre del fichero).&lt;br /&gt;&lt;br /&gt;Y para más coña, &lt;a href="http://httpd.apache.org/"&gt;Apache&lt;/a&gt; lo genera por defecto a partir del INode, Fecha y Tamaño del fichero en cuestión. Desde mi punto de vista no aporta nada, consume recursos, obliga a enviar cabeceras innecesarias, y además puede dar "falsos negativos" en granjas o entornos balanceados o después de un despliegue de una aplicación (mismo fichero pero en otro inodo!).&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.sun.com/software/products/web_srvr/index.xml"&gt;iPlanet / Sun ONE Web Server&lt;/a&gt; (al menos hasta la versión 6.1) también lo pone por defecto y también se recomienda eliminarlo para mejorar el rendimiento.&lt;br /&gt;&lt;br /&gt;Pero además, en Apache me he encontrado con otro problema: si está activado el mod_deflate para la compresión de contenidos, Apache nunca se da por enterado de que el fichero solicitado sí es el mismo que tiene el usuario en su cache, así que siempre devuelve un "200 OK" + todo el contenido, en lugar de un "304 Not Modified". Es porque al ETag enviado al cliente se le añade el sufijo "-gzip" al ETag, y es lo que el cliente envía de vuelta... pero por lo que sea Apache no es capaz de entender que el ETag con GZIP debería ser el mismo que el ETag sin GZIP. Es decir, da igual cómo se haya transportado el contenido, lo importante es si lo que hay en el servidor es lo mismo que tiene la caché del cliente ¿o no?&lt;br /&gt;&lt;br /&gt;Bueno. ¿Y cómo se elimina? Afortunadamente de forma muy &lt;a href="http://httpd.apache.org/docs/2.2/mod/core.html#fileetag"&gt;sencilla&lt;/a&gt; (para Apache):&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;code&gt;FileETag None&lt;/code&gt;&lt;/blockquote&gt;&lt;br /&gt;Y para iPlanet 6.1 &lt;a href="http://wikis.sun.com/display/WebServer/faq_configuration#faq_configuration-5.HowcanIdisableETagfromtheresponseheader%3F"&gt;también es trivial&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;code&gt;&amp;lt;Object name="default"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(...)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Output fn="set-variable" remove-srvhdrs="etag"&lt;br /&gt;&amp;lt;/Object&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/blockquote&gt;&lt;br /&gt;Para más información de por qué esto mejora el rendimiento:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.askapache.com/htaccess/apache-speed-etags.html"&gt;http://www.askapache.com/htaccess/apache-speed-etags.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://developer.yahoo.net/blog/archives/2007/07/high_performanc_11.html"&gt;http://developer.yahoo.net/blog/archives/2007/07/high_performanc_11.html&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Dejo por aquí también referencia al RFC de HTTP/1.1 en lo que a cabeceras se refiere. Cuántas veces he tirado de él y qué poco de moda está a día de hoy tener tiempo para leer RFCs, sino mejor buscar en blogs... ;-)&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html"&gt;http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-7092112629987147138?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/7092112629987147138/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=7092112629987147138' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/7092112629987147138'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/7092112629987147138'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/12/eliminar-etags-para-incrementar-el.html' title='Eliminar ETags para incrementar el rendimiento'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-8559620369631496917</id><published>2008-12-05T23:20:00.000+01:00</published><updated>2008-12-05T23:20:00.861+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='General'/><title type='text'>Java Performance Community</title><content type='html'>Tres enlaces de interés: &lt;ul&gt;&lt;li&gt;&lt;strong&gt;Performance group&lt;/strong&gt; @ java.net: &lt;a href="https://performance.dev.java.net/home/"&gt;https://performance.dev.java.net/home/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;General Performance Discussion&lt;/strong&gt; @ java.net: &lt;a href="http://forums.java.net/jive/forum.jspa?forumID=60&amp;amp;start=15"&gt;http://forums.java.net/jive/forum.jspa?forumID=60&amp;amp;start=15&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Performance tuning&lt;/strong&gt; @ javapedia: &lt;a href="http://wiki.java.net/bin/view/Javapedia/PerformanceTuning"&gt;http://wiki.java.net/bin/view/Javapedia/PerformanceTuning&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Java Performance Tuning &lt;/strong&gt;portal: &lt;a href="http://www.javaperformancetuning.com/"&gt;http://www.javaperformancetuning.com/&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;/ul&gt;&lt;br /&gt;&lt;a href="https://performance.dev.java.net/"&gt;&lt;img style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="https://performance.dev.java.net/files/documents/3652/16604/javaperf_150.png" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-8559620369631496917?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/8559620369631496917/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=8559620369631496917' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/8559620369631496917'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/8559620369631496917'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/12/java-performance-community.html' title='Java Performance Community'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-3665309862487534072</id><published>2008-12-02T23:11:00.004+01:00</published><updated>2008-12-02T23:18:16.379+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JDK/JVM'/><title type='text'>Ahora sí: Java 6 update 11</title><content type='html'>Pues unas horas después de la &lt;a href="http://serverperformance.blogspot.com/2008/12/salida-nula-java-6-update-11-6u11.html"&gt;salida nula&lt;/a&gt;... ya está disponible el 6u11 en &lt;a href="http://java.sun.com/javase/downloads/"&gt;http://java.sun.com/javase/downloads/&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Como os comentaba, y podéis ver en las &lt;a href="http://java.sun.com/javase/6/webnotes/6u11.html"&gt;notas de la versión&lt;/a&gt;, incluye:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;13 fixes de vulnerabilidades de seguridad.&lt;/li&gt;&lt;li&gt;18 fixes de otros bugs, sólo uno de Hotspot, y principalmente relacionados con los gráficos y el plugin (vamos, los grandes cambios de la 6u10 en ambos aspectos han generado alguna cagadilla)&lt;/li&gt;&lt;li&gt;16 fixes en VisualVM&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Así que, parece que aunque la excusa de los updates impares son actualizaciones de seguridad, este en concreto lo han tenido que adelantar para arregar alguna cagadilla de la última release de hace 45 días.&lt;/p&gt;&lt;p&gt;Espero que la política de Sun no cambie hacia la "beta permanente" que está poniendo de moda Google y que amparamos bajo el nombre genérico de metodologías ágiles... y que tiene sentido en servicios/aplicaciones modelos SaaS... ¡pero no en esto, coño!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-3665309862487534072?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/3665309862487534072/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=3665309862487534072' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/3665309862487534072'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/3665309862487534072'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/12/ahora-s-java-6-update-11.html' title='Ahora sí: Java 6 update 11'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-239548334611857151</id><published>2008-12-02T14:57:00.000+01:00</published><updated>2008-12-02T23:09:11.924+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JDK/JVM'/><title type='text'>Salida nula: Java 6 Update 11 (6u11)</title><content type='html'>&lt;a href="http://1.bp.blogspot.com/_4ZEuwiCuF6A/STVhH1Yqj-I/AAAAAAAAAH8/jx4Lx2IYb8g/s1600-h/salida.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5275229325751914466" style="FLOAT: right; MARGIN: 0px 0px 10px 10px; WIDTH: 320px; CURSOR: hand; HEIGHT: 217px" alt="" src="http://1.bp.blogspot.com/_4ZEuwiCuF6A/STVhH1Yqj-I/AAAAAAAAAH8/jx4Lx2IYb8g/s320/salida.jpg" border="0" /&gt;&lt;/a&gt;Ummm...&lt;br /&gt;&lt;br /&gt;Pues ha debido haber alguna "salida nula" en Sun o algún bug detectado a última hora, o alguien que ha tenido el dedo del gatillo demasiado rápido.&lt;br /&gt;&lt;br /&gt;Porque en algún momento entre el día 1 y el 2 de diciembre (hoy) Sun ha liberado el Update 11 (6u11) del JDK/JRE pero a continuación lo han vuelto a eliminar de la página de descargas.&lt;br /&gt;&lt;br /&gt;He visto la reseña en este post: &lt;a href="http://blogs.sun.com/nbprofiler/entry/jdk_6_update_11_comes"&gt;http://blogs.sun.com/nbprofiler/entry/jdk_6_update_11_comes&lt;/a&gt; y efectivamente como indica alguno de los comentaristas si googleas "Java SE Development Kit (JDK) 6 Update 11" ya está indexado...&lt;br /&gt;&lt;br /&gt;Como comentaba en la entrada &lt;a href="http://serverperformance.blogspot.com/2008/11/schedule-de-siguientes-updates-de-java.html"&gt;Schedule de siguientes updates de Java 6. Versiones de Hotspot y compatibilidad entre ellas&lt;/a&gt;, se esperaba que este 6u11 sóo contuviera actualizaciones de seguridad pero por lo que parece incluye también al menos una actualización de VisualVM. Pero tiene que haber alguna actualización de seguridad porque si no, no se explica esta aceleración en el tiempo entre updates. ¿Menos de 2 meses? Ummm...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-239548334611857151?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/239548334611857151/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=239548334611857151' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/239548334611857151'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/239548334611857151'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/12/salida-nula-java-6-update-11-6u11.html' title='Salida nula: Java 6 Update 11 (6u11)'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_4ZEuwiCuF6A/STVhH1Yqj-I/AAAAAAAAAH8/jx4Lx2IYb8g/s72-c/salida.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-6103287426988716566</id><published>2008-11-27T21:21:00.004+01:00</published><updated>2008-11-28T10:34:09.420+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='HTTP/S'/><category scheme='http://www.blogger.com/atom/ns#' term='Glassfish/Tomcat'/><category scheme='http://www.blogger.com/atom/ns#' term='Criptografía/HSM'/><category scheme='http://www.blogger.com/atom/ns#' term='Apache'/><title type='text'>HOWTO: Importar un certificado servidor de Apache en un almacén JKS</title><content type='html'>&lt;em&gt;[Offtopic: Esta entrada no habla sobre rendimiento]&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;Si tenemos un servidor Apache configurado para atender por SSL con su certificado servidor y su clave privada, y queremos utilizar el mismo certificado servidor en una aplicación Java, ¿cómo hacerlo?&lt;br /&gt;&lt;br /&gt;Usos: por ejemplo si queremos eliminar Apache como proxy inverso y que nuestro motor de servlets (Glassfish, Tomcat o lo que sea) sea el frontal web directamente, o si queremos utilizar el mismo certificado que tenemos en el Apache para otros propósitos como por ejemplo en un servidor FTPS hecho en Java (como &lt;a href="http://mina.apache.org/"&gt;Apache Mina&lt;/a&gt;) o cualquier otro servicio paralelo.&lt;br /&gt;&lt;br /&gt;Para ello lo más sencillo es utilizar un PKCS#12 pivote, que luego podremos eliminar.&lt;br /&gt;&lt;br /&gt;Comandos: &lt;blockquote&gt;&lt;code&gt;&lt;br /&gt;$ openssl pkcs12 -export -in &amp;lt;certificado.cert&amp;gt; -inkey &amp;lt;claveprivada.key&amp;gt; -out &amp;lt;pkcs12.p12&amp;gt;&lt;br /&gt;$ keytool -importkeystore -srckeystore &amp;lt;pkcs12.p12&amp;gt; -srcstoretype PKCS12 -destkeystore &amp;lt;almacen.jks&amp;gt; -deststoretype JKS&lt;/code&gt;&lt;/blockquote&gt;&lt;br /&gt;Obviamente, reemplazar &amp;lt;certificado.cert&amp;gt;, &amp;lt;claveprivada.key&amp;gt;, &amp;lt;pkcs12.p12&amp;gt; y &amp;lt;almacen.jks&amp;gt; por los nombres adecuados (ficheros origen utilizados por nuestro Apache, y JKS destino que se utilizará por nuestra aplicación Java).&lt;br /&gt;&lt;br /&gt;Nota: la opción -importkeystore sólo es válida a partir de Java 6. En JDKs antiguos se utiliza "-import -pkcs12" (creo, pero tendría que tirar de archivo...)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-6103287426988716566?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/6103287426988716566/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=6103287426988716566' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/6103287426988716566'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/6103287426988716566'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/10/howto-importar-un-certificado-servidor.html' title='HOWTO: Importar un certificado servidor de Apache en un almacén JKS'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-3910261051267936776</id><published>2008-11-23T14:25:00.003+01:00</published><updated>2008-11-24T10:03:55.055+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JDK/JVM'/><title type='text'>Compatibilidad entre versiones de Hotspot y versiones del JDK</title><content type='html'>&lt;a href="http://4.bp.blogspot.com/_4ZEuwiCuF6A/SQxaKTsYpII/AAAAAAAAAHk/7C3FcmaMShU/s1600-h/java.png"&gt;&lt;img id="BLOGGER_PHOTO_ID_5263681197620896898" style="FLOAT: left; MARGIN: 0px 10px 10px 0px; WIDTH: 190px; CURSOR: hand; HEIGHT: 187px" alt="" src="http://4.bp.blogspot.com/_4ZEuwiCuF6A/SQxaKTsYpII/AAAAAAAAAHk/7C3FcmaMShU/s400/java.png" border="0" /&gt;&lt;/a&gt;Este es mi descubrimiento más curioso de todos en los últimos meses. Lo que en realidad me resulta curioso es no haberlo sabido/intuido hasta ahora. Es bueno estar siempre aprendiendo cosas nuevas, y es bueno también bajarse los humos uno mismo de vez en cuando... &lt;p&gt;Tradicionalmente muchos suelen confundir JDK y JVM. Pero son dos cosas distintas, una cosa es la versión de las bibliotecas Java, versión de bytecode y compilación javac (JDK) y otra muy distinta es la máquina virtual que ejecuta las aplicaciones Java. Esto lo he tenido claro siempre, lo que no sabía es que Hotspot tiene compatibilidad hacia atrás con versiones anteriores del JDK...&lt;/p&gt;&lt;p&gt;Con JRockit, esta diferenciación siempre ha estado muy clara, tanto por los usuarios como sobre todo por el equipo de JRockit/Bea/Oracle/quien_les_compre_a_continuación. Ellos distribuyen una versión de su VM "empaquetada" junto con una versión del JDK. De hecho, la versión JRockit 27.5 es compatible con JDK 1.4, JDK 1.5 y Java 6. Misma VM, diferente JDK en el paquete.&lt;/p&gt;&lt;p&gt;Pero estas semanas he estado haciendo pruebas y hablando con los ingenieros de Sun, resulta que Hotspot también es independiente del JDK y compatible hacia atrás con todos ellos (desde JDK 1.7 hasta JDK 1.5). En concreto he conseguido hacer funcionar con éxito y sin problemas aplicaciones sobre JDK 1.5 con Hotspot 14-b05 (distibuido en JDK 7 early access), y también el 6u6p con el mismo Hotspot 14 en lugar de el 13, que es el que venía por defecto...&lt;/p&gt;&lt;p&gt;¿Cómo se hace? Sencillo. Basta con identificar la bilioteca jvm de nuestro JRE y reemplazarla por la deseada. Algunos ejemplos:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;En Windows, es el fichero jvm.dll que se encuentra tanto en &lt;code&gt;&amp;lt;jre&amp;gt;\bin\server&lt;/code&gt; como en &lt;code&gt;&amp;lt;jre&amp;gt;\bin\client&lt;/code&gt; (ojo, por supuesto que en realidad son distintas versiones, Hotspot cliente y Hotspot servidor)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;En Linux x64, es el fichero libjvm.so que se encuentra en &lt;code&gt;&amp;lt;jre&amp;gt;/lib/amd64/server&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Del mismo modo, si no recuerdo mal, podemos poner la biblioteca jvm de JRockit en un directorio de instalación del JRE de Sun y viceversa. Es decir, la VM (Hotspot, JRockit, etc) es simplemente el libjvm.so si no me equivoco!&lt;/p&gt;&lt;p&gt;Lo que desde ya te puedo asegurar es que modificar la combinación JDK-JVM no está soportada por Sun. Así que, como suele decirse en estos casos... "Do it at your own risk!". Esto es lo que me dicen desde el equipo de Hotspot extraoficialmente cuando he preguntado por ello:&lt;/p&gt;&lt;p&gt;&lt;blockquote&gt;&lt;em&gt;"Yes, for practical purposes, the latest HotSpot VMs should be compatible with JDKs back to 1.5, and we in engineering try hard to make that possible.&lt;br /&gt;&lt;br /&gt;Sun, as a company, doesn't guarantee complete backward compatibility because of the huge testing matrix that would re required to verify each HotSpot release with every prior JDK. (We support more many more platforms than JRockit.)&lt;br /&gt;&lt;br /&gt;So a customer can try out an new VM with an old JDK, but don't run your enterprise on it, and don't ask Sun to support it. ;-)"&lt;/em&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;:-)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-3910261051267936776?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/3910261051267936776/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=3910261051267936776' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/3910261051267936776'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/3910261051267936776'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/11/compatiblidad-entre-versiones-de.html' title='Compatibilidad entre versiones de Hotspot y versiones del JDK'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_4ZEuwiCuF6A/SQxaKTsYpII/AAAAAAAAAHk/7C3FcmaMShU/s72-c/java.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-3343254160356391718</id><published>2008-11-18T20:59:00.003+01:00</published><updated>2008-11-21T10:28:02.476+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JDK/JVM'/><title type='text'>Schedule de siguientes updates de Java 6. Versiones de Hotspot y compatibilidad entre ellas</title><content type='html'>&lt;a href="http://3.bp.blogspot.com/_4ZEuwiCuF6A/SQxbaF4sxLI/AAAAAAAAAHs/kymklNTki1s/s1600-h/schedule.gif"&gt;&lt;img id="BLOGGER_PHOTO_ID_5263682568303985842" style="FLOAT: left; MARGIN: 0px 10px 10px 0px; WIDTH: 160px; CURSOR: hand; HEIGHT: 142px" alt="" src="http://3.bp.blogspot.com/_4ZEuwiCuF6A/SQxbaF4sxLI/AAAAAAAAAHs/kymklNTki1s/s320/schedule.gif" border="0" /&gt;&lt;/a&gt;Como veis, estoy dosificando (demasiado) la información que he obtenido de mi interacción con el equipo de ingenieros de Hotspot en Sun, que ha sido muy interesante y emocionante al mismo tiempo.&lt;br /&gt;&lt;br /&gt;Como diría un amigo mío, a mi edad y aún sigo emoocionándome con chorradas... :-)&lt;br /&gt;&lt;br /&gt;Y creo que ahora estoy dando una primicia.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Ni que decir tiene que esta información es absolutamente extraoficial (aunque probablemente el calendaro previsto sea público a colaboradores, seguro que está por &lt;a href="https://jdk6.dev.java.net/"&gt;https://jdk6.dev.java.net/&lt;/a&gt; pero no he tenido tiempo de chequearlo) y que el calendario final puede variar por muy distintos motivos. Tampoco aseguro que la información sea verídica, es la que me han pasado desde dentro, eso sí que lo aseguro...&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Calendario previsto de siguientes updates de Java 6:&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Java 6 update 10 (6u10 / 1.6.0_10): &lt;/strong&gt;recién liberado el 15 de octubre, con la nueva microarquitectura&lt;/li&gt;&lt;li&gt;&lt;em&gt;Java 6 update 11 (6u11 / 1.6.0_11):&lt;/em&gt; reservado para posibles actualizaciones de seguridad, puede que no se produzca si no es necesario&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Java 6 update 12 (6u12 / 1.6.0_12):&lt;/strong&gt; planificado para Febrero o Marzo de 2009&lt;/li&gt;&lt;li&gt;&lt;em&gt;Java 6 update 13 (6u13 / 1.6.0_13):&lt;/em&gt; reservado para posibles actualizaciones de seguridad, puede que no se produzca si no es necesario&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Java 6 update 14 (6u14 / 1.6.0_14):&lt;/strong&gt; Planificado para Mayo o Junio de 2009&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;Correspondencia entre versiones de Hotspot y distribuciones de Java 6:&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Hotspot 10:&lt;/strong&gt; incluido desde Java 6u04 (con diferentes builds y fixes en sucesivos updates u05, u06 y u07).&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Hotspot 11:&lt;/strong&gt; ya incluido en Java 6u10.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Hotspot 12: &lt;/strong&gt;¿? creo que nunca se liberará, por mis noticias es una vía muerta.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Hotspot 13:&lt;/strong&gt; fue incluido en Java 6u6p ("performance release") a modo de anticipo de futuras mejoras de rendimiento, pero tiene algunos bugs reconocidos como el que indiqué en el anterior post. Dudo que lo incluyan en 6u12, seguramente dará paso a Hotspot 14 directamente...&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Hotspot 14:&lt;/strong&gt; su build 05 está actualmente incluido en Java 7 (desde algun snapshot relativamente reciente, no recuerdo cuál) y está previsto su lanzamiento para entornos productivos con Java 6 Update 14 (6u14). Es posible que se libere en 6u12 si consiguen solucionar ciertos problemas de estabilidad que actualmente tienen, aunque lo más probable es que no sea así y tengamos esperar a mayo-junio pues...&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;O lo que es lo mismo, salvo que haya fixes de seguridad, tengo bastante claro que dejaré mis entornos de producción estables con 6u07 hasta junio (quizás actualice a 6u10 en enero). Y entonces migrar en los entornos de Pruebas y comenzar la certificación... o sea, que preveo que actualizaré Producción después de verano, dando el salto desde Java 6u7 a 6u14...&lt;/p&gt;&lt;p&gt;:-)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-3343254160356391718?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/3343254160356391718/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=3343254160356391718' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/3343254160356391718'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/3343254160356391718'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/11/schedule-de-siguientes-updates-de-java.html' title='Schedule de siguientes updates de Java 6. Versiones de Hotspot y compatibilidad entre ellas'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_4ZEuwiCuF6A/SQxbaF4sxLI/AAAAAAAAAHs/kymklNTki1s/s72-c/schedule.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-4905719739591537250</id><published>2008-11-17T09:51:00.004+01:00</published><updated>2008-11-21T10:25:51.557+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Sincronización'/><category scheme='http://www.blogger.com/atom/ns#' term='Memoria'/><title type='text'>"What volatile means in Java" exposed by Jeremy Manson</title><content type='html'>Para quienes no sepan de él, &lt;a href="http://jeremymanson.blogspot.com/"&gt;Jeremy Manson&lt;/a&gt; es una de las eminencias y referencias en el mundo de la concurrencia Java y en el modelo de memoria Java, de hecho, fue uno de los papás del "nuevo" modelo de memoria Java allá por 2004-2005. Curra en Google, lo cual dice algo sobre su nivel, y hay a quien se le hace el culo pepsicola con estas cosas... (por eso lo menciono :-) Y es un tipo excepcionalmente abierto y amable aun cuando sabe que no tienes razón en lo que le expones, podéis buscar mis interacciones con él en su blog :-)&lt;br /&gt;&lt;br /&gt;Jeremy ya lo expuso bastante bien en sus anteriores posts (que yo referencié &lt;a href="http://serverperformance.blogspot.com/2008/07/double-checked-locking-por-fin-funciona.html"&gt;aquí&lt;/a&gt;), y en realidad este no da excesiva información adicional. Pero está bastante bien explicado y con algún gráfico que se agradece...&lt;br /&gt;&lt;br /&gt;Así que no me enrollaré mucho más. Ahí van los enlaces a sus tres posts acerca de las variables volátiles en el modelo de memoria Java:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://jeremymanson.blogspot.com/2008/11/what-volatile-means-in-java.html"&gt;http://jeremymanson.blogspot.com/2008/11/what-volatile-means-in-java.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://jeremymanson.blogspot.com/2008/05/double-checked-locking.html"&gt;http://jeremymanson.blogspot.com/2008/05/double-checked-locking.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://jeremymanson.blogspot.com/2007/08/volatile-does-not-mean-atomic.html"&gt;http://jeremymanson.blogspot.com/2007/08/volatile-does-not-mean-atomic.html&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Y esta es una gran PPT sobre el modelo de memoria en Java, escrito por el propio Manson &lt;em&gt;et al.&lt;/em&gt;:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.inf.ethz.ch/personal/daniekro/classes/se-sem/ss2005/slides/sgier.pdf"&gt;http://www.inf.ethz.ch/personal/daniekro/classes/se-sem/ss2005/slides/sgier.pdf&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;P.D: He actualizado también &lt;a href="http://serverperformance.blogspot.com/2008/07/double-checked-locking-por-fin-funciona.html"&gt;el post de julio sobre double-checked-locking &lt;/a&gt;con esta información... &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-4905719739591537250?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/4905719739591537250/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=4905719739591537250' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/4905719739591537250'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/4905719739591537250'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/11/what-volatile-means-in-java-exposed-by.html' title='&quot;What volatile means in Java&quot; exposed by Jeremy Manson'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-6841082000733916396</id><published>2008-11-12T08:02:00.009+01:00</published><updated>2008-11-21T10:25:55.187+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='HTTP/S'/><category scheme='http://www.blogger.com/atom/ns#' term='Glassfish/Tomcat'/><category scheme='http://www.blogger.com/atom/ns#' term='Apache'/><title type='text'>Uso de Apache como proxy inverso de Glassfish V2</title><content type='html'>&lt;a href="http://3.bp.blogspot.com/_4ZEuwiCuF6A/SRqtBkZ0gZI/AAAAAAAAAH0/P0jma-Njcu0/s1600-h/Apache.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5267712956626665874" style="FLOAT: left; MARGIN: 0px 10px 10px 0px; WIDTH: 320px; CURSOR: hand; HEIGHT: 240px" alt="" src="http://3.bp.blogspot.com/_4ZEuwiCuF6A/SRqtBkZ0gZI/AAAAAAAAAH0/P0jma-Njcu0/s320/Apache.jpg" border="0" /&gt;&lt;/a&gt;Aunque en muchos escenarios sería más que discutible... una práctica bastante habitual es tener un proxy inverso que sirva el contenido estático, haga balanceo y algunas reglas de seguridad delante de nuestro Glassfish.&lt;br /&gt;&lt;br /&gt;Como digo es algo muy discutible en el 75% de los casos, la mayor parte de al gente lo hace como "buena práctica" y punto, pero no siempre hace falta y a cambio se complica un poquito más el sistema... Si se hace sólo por rendimiento, a día de hoy no tiene sentido porque Grizzly (el motor http de Glassfish) es muy óptimo y lo que se gana por un lado se pierde en las comunicaciones entre el proxy inverso y la aplicación final. Pero si se hace por seguridad (suele ser la excusa pero en la mayor parte de los escenarios no aporta nada, sobre todo si se ejecuta en la misma máquina que el Glassfish, je, je), o por balanceo de cargas o por caches, etc, etc. Entonces me callo. Sí que hace falta. Y es muy buena idea que sea Apache el servidor web escogido.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;En cualquier caso. ¿Cómo hacer que un Apache 2 / 2.2 sea el frontal HTTP para nuestro Glassfish?&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Espero que en V3 den soporte bien dado, para Glassfish V2 hay que hacerlo con mod_jk en el lado Apache y &lt;strong&gt;copiando&lt;/strong&gt; unos jars de Tomcat 5.5 en el lado Glassfish. Sí lo habéis leído bien...&lt;br /&gt;&lt;br /&gt;En todos estos enlaces están las instrucciones:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://weblogs.java.net/blog/amyroh/archive/2006/08/glassfish_suppo.html"&gt;http://weblogs.java.net/blog/amyroh/archive/2006/08/glassfish_suppo.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://weblogs.java.net/blog/jfarcand/archive/2006/03/running_glassfi_1.html"&gt;http://weblogs.java.net/blog/jfarcand/archive/2006/03/running_glassfi_1.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blogs.sun.com/jluehe/entry/supporting_apache_loadbalancer_with_glassfish"&gt;http://blogs.sun.com/jluehe/entry/supporting_apache_loadbalancer_with_glassfish&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blogs.sun.com/dadelhardt/entry/loadbalancing_with_mod_jk_and_glassfish"&gt;http://blogs.sun.com/dadelhardt/entry/loadbalancing_with_mod_jk_and_glassfish&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Pero, oh sorpresa, resulta que en los últimos meses las cosas han cambiado. Tomcat 6 no trae ningún tomcat_apj.jar (sino que lo han integrado en tomcat_coyote.jar) y la implementación en las versiones más recientes de Tomcat 5.5 no es compatible con Glassfish V2. ¿Te sale esta excepción al hacer una request?:&lt;/p&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;code&gt;&lt;strong&gt;java.lang.NoSuchFieldError: USE_CUSTOM_STATUS_MSG_IN_HEADER&lt;/strong&gt;&lt;br /&gt;at org.apache.jk.common.JkInputStream.appendHead JkInputStream.java:283)&lt;br /&gt;at org.apache.jk.core.MsgContext.action(MsgContext.java:267)&lt;br /&gt;at org.apache.coyote.Response.action(Response.java:221)&lt;br /&gt;at org.apache.coyote.Response.sendHeaders(Response.java:416)&lt;br /&gt;at org.apache.coyote.tomcat5.OutputBuffer.doFlush(OutputBuffer.java:355)&lt;br /&gt;at org.apache.coyote.tomcat5.OutputBuffer.close(OutputBuffer.java:321)&lt;br /&gt;at org.apache.coyote.tomcat5.CoyoteResponse.finishResponse(CoyoteResponse.java:578)&lt;br /&gt;at org.apache.coyote.tomcat5.CoyoteAdapter.afterService(CoyoteAdapter.java:318)&lt;/code&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Si esta es la excepción, esta es tu solución: coge el tomcat_apj.jar de Tomcat 5.5.23 y no de ninguna posterior (actualmente van por la 5.5.27 en la rama 5.5). Y funciona perfectamente.&lt;br /&gt;&lt;br /&gt;Al César lo que es del César, a mi me ha salvado la vida esta entrada: &lt;a href="http://www.albeesonline.com/blog/2008/10/10/javalangnosuchfielderror-use_custom_status_msg_in_header/"&gt;http://www.albeesonline.com/blog/2008/10/10/javalangnosuchfielderror-use_custom_status_msg_in_header/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Todo una guarrada, ¿verdad? Lo cierto es que dice poco del equipo de diseño de Glassfish, es como si no hubieran pensado en implantaciones "para el mundo real"... ¿?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-6841082000733916396?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/6841082000733916396/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=6841082000733916396' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/6841082000733916396'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/6841082000733916396'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/11/uso-de-apache-como-proxy-inverso-de.html' title='Uso de Apache como proxy inverso de Glassfish V2'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_4ZEuwiCuF6A/SRqtBkZ0gZI/AAAAAAAAAH0/P0jma-Njcu0/s72-c/Apache.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-6885802844277264536</id><published>2008-11-08T01:18:00.003+01:00</published><updated>2008-11-21T10:28:24.266+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JDK/JVM'/><category scheme='http://www.blogger.com/atom/ns#' term='Escape analysis'/><title type='text'>Identificación de bugs en la versión 6u6p y workaround</title><content type='html'>&lt;a href="http://www.workarounds.com/"&gt;&lt;img id="BLOGGER_PHOTO_ID_5263672172638618386" style="FLOAT: right; MARGIN: 0px 0px 10px 10px; WIDTH: 320px; CURSOR: hand; HEIGHT: 240px" alt="" src="http://1.bp.blogspot.com/_4ZEuwiCuF6A/SQxR8_A7wxI/AAAAAAAAAHU/ni7Xxm8Vktc/s320/coffeetime_lrg.jpg" border="0" /&gt;&lt;/a&gt; &lt;div&gt;Como indiqué en el post &lt;a href="http://serverperformance.blogspot.com/2008/09/6u6-p-pues-en-linux-x64-peta.html"&gt;6u6-p: Pues en Linux x64 peta!!!!!!!&lt;/a&gt;, en mis entornos servidor tuve problemas en la versión 6u6p. Tras enviar el feedback a Sun, los ingenieros del Hotspot se pusieron en contacto conmigo e hicimos múltiples pruebas.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;El trato ha sido maravilloso, y estoy encantado de haber podido ayudar a identificar el problema, aunque he de decir que ya lo tenían resuelto, je je.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Tras varias semanas, por fin hemos llegado a la conclusión de que se trataba de un problema con el análisis de escape (ver para más información sobre Escape Analysis, ver los posts &lt;a href="http://serverperformance.blogspot.com/2008/08/allocation-deallocation-and-escape.html"&gt;Allocation, deallocation and escape analysis for Java&lt;/a&gt; y &lt;a href="http://serverperformance.blogspot.com/2008/09/funcionan-las-optimizaciones-sobre-el.html"&gt;¿Funcionan las optimizaciones sobre el modelo de threading?&lt;/a&gt; ), que ya estaba identificado en el bug 6726999 y que han resuelto en la versión 14 de Hotspot, cuyo build 05 por cierto se distribuye con los Early Access del JDK 7 y que está previsto que se incorpore en Java 6 en un update aproximadamente en mayo-junio. Habrá que esperar pues...&lt;/div&gt;&lt;br /&gt;&lt;div&gt;He aprendido varias cosas de las interioridades de Hotspot y de versiones, pero tengo otros posts preparados para eso... De momento sólo diré que con el nuevo 6u10 por fin se distribuye Hotspot 11, pero el desarrollo del mismo ya va por la versión 14... Como podréis imaginaros, la evolución a nivel de Hotspot está siendo espectacular aunque tenemos que esperar para ver cada versión en la calle...&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Me han pasado también varias versiones del libjvm.so, en concreto versiones "fastdebug" que tracean información de ejecución y compilación, y tiene además toneladas de asserts. Por ejemplo, algunos parámetros de lanzamiento interesantes para las VM fastdebug:&lt;/div&gt;&lt;ul&gt;&lt;li&gt;-XX:+LogCompilation: para escribir en un fichero hotspot.log y en el especificado arriba información acerca de la compilación binaria en tiempo real&lt;/li&gt;&lt;li&gt;-XX:SuppressErrorAt=&lt;cpp&gt; (por ejemplo -XX:SuppressErrorAt=/xmlstream.cpp:119) para que no se ejecute un cierto assert&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;A lo que íbamos. Aparte de todo este rollo, el único workaround de momento, si se quiere funcionar con la 6u6p en producción es ejecutarlo con el parámetro de lanzamiento &lt;strong&gt;-XX:-DoEscapeAnalaysis&lt;/strong&gt;. Yo no voy a hacerlo, prefiero seguir con Java 6u07 en producción pero con esa opción habilitada (porque ejecuto bastantes clases compiladas para JDK 1.4, aggg, y está lleno de StringBuffers, que se benefician bastante de los análisis de escape, aunque en Hotspot 10 estén hastante limitados de momento.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Además, dejo una perlita... en toda la interacción con el equipo de ingenieros de Hotspot, me han dado información extraoficial acerca de fechas previstas de liberación de las siguientes actualizaciones de Java 6 y sus correspondencias con versiones de Hotspot. Esto lo publicaré en el siguiente post...&lt;/div&gt;&lt;br /&gt;&lt;div&gt;:-)&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-6885802844277264536?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/6885802844277264536/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=6885802844277264536' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/6885802844277264536'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/6885802844277264536'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/11/identificacin-de-bugs-en-la-versin-6u6p.html' title='Identificación de bugs en la versión 6u6p y workaround'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_4ZEuwiCuF6A/SQxR8_A7wxI/AAAAAAAAAHU/ni7Xxm8Vktc/s72-c/coffeetime_lrg.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-8769813026826845708</id><published>2008-11-03T05:06:00.003+01:00</published><updated>2008-11-21T10:28:18.297+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JDK/JVM'/><title type='text'>Lanzamiento de Java 6u10</title><content type='html'>&lt;em&gt;[Actualizado el 6/11/2008: algunas correcciones y ampliación del resumen ejecutivo con mis conclusiones]&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;Sun liberó el pasado día 15 de octubre por fin Java 6 update 10 (6u10), que puede descargar como siempre de &lt;a href="http://java.sun.com/javase/downloads/"&gt;http://java.sun.com/javase/downloads/&lt;/a&gt;, tras mucho tiempo en beta y release candidate...&lt;br /&gt;&lt;br /&gt;Nota: la noticia tiene ya 15 días, pero he preferido no escribir sobre ello hasta haberlo probado, claro :-)&lt;br /&gt;&lt;br /&gt;Se trata de un hito importante (llevaban en beta bastante tiempo) porque supone una pequeña revolución tecnológica al menos para usos "de escritorio". De hecho, si os fijáis ha habido un salto entre el anterior update (6u07) y este (6u10), es debido a que se empezarons a librerar versiones beta más o menos a la vez que la 6u06, y dejaron margen a updates de seguridad por si se retrasaba más de lo esperado.&lt;br /&gt;&lt;br /&gt;Pueden verse los detalles en:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://java.sun.com/javase/6/webnotes/6u10.html"&gt;http://java.sun.com/javase/6/webnotes/6u10.html&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href="http://java.sun.com/javase/6/6u10faq.jsp"&gt;http://java.sun.com/javase/6/6u10faq.jsp&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://java.sun.com/javase/6/docs/technotes/guides/jweb/otherFeatures/jre_install.html"&gt;http://java.sun.com/javase/6/docs/technotes/guides/jweb/otherFeatures/jre_install.html&lt;/a&gt;, &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Aquí mi resumen ejecutivo: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;No se incluyen actualizaciones resoluciones de vulnerabilidades de seguridad. Por lo tanto la versión 6u7 está igual de actualizado que 6u10 en este aspecto.&lt;/li&gt;&lt;li&gt;Resolución de múltiples bugs, la mayoría afectando al uso de escritorio, entorno gráfico e instalación, pero algunos también son temas estrella en las versiones servidor, por ejemplo por fin han eliminado la limitación en el tamaño de heap por defecto a 1,4 GBytes en Windows x64 (se mantiene en Windows x32 por la limitación del espacio de direcciones a 2 gigas), además de corregir un memory leak con el modelo ParalellOlgGC de Garbage Collector (es el modelo paralelo que utilizo yo).&lt;/li&gt;&lt;li&gt;Se incorpora por fin la versión 11 de Hostpot, desde 6u4 se mantenía la versión Hotspot 10, con mejoras de rendimiento tanto para cliente como para servidor, además de resolución de bugs como los mencionados arriba&lt;/li&gt;&lt;li&gt;Nueva implementación del renderizado Direct3D para Windows, incluyendo (¡por fin!) aceleración hardware, aunque de momento sólo esté implementada para tarjetas ATI u nVidia).&lt;/li&gt;&lt;li&gt;Refactorización del JRE. El JRE ahora consta de un núcleo (kernel) mínimo y se instalan distintos bundles en función de las necesidades (ver documentación para más detalles).&lt;/li&gt;&lt;li&gt;Reingeniería del Plugin. Menudo revolcón le han dado, ya no es un pluggin "para apllets Java" sino que además integra las nuevas tecnologías &lt;a href="http://es.wikipedia.org/wiki/JNLP"&gt;JNLP &lt;/a&gt;y &lt;a href="http://es.wikipedia.org/wiki/JavaFX"&gt;JavaFX&lt;/a&gt;. Importante: La gestión de applets tiene cambios significativos, incluyendo el tratamiento de applets no firmados, ver las release notes...&lt;/li&gt;&lt;li&gt;Y ¡por fin!, mejor control de versiones, elección de qué versión usar en caso de tener varias instaladas... y lo más importante de todo: la actualización puede funcionar en modo parche para no tener varios directorios con distintos updates del JDK instalado. Con lo molesto que era hasta hahora consolidar todo esto a mano. Por cierto que manda huevos que no lo hayan hecho hasta ahora.&lt;/li&gt;&lt;/ul&gt;Yo ya lo tengo instalado en mi PC, y funcionando con Netbeans y SQLDeveloper sin problema. Por cierto que he actualizado el post &lt;a href="http://serverperformance.blogspot.com/2008/10/rendimiento-del-netbeans6.html"&gt;Tuning de NetBeans 6 (y NetBeans 6.1)&lt;/a&gt; para reflejar mi nueva configuración con aceleración gráfica por hardware, je je.&lt;br /&gt;&lt;br /&gt;También lo hemos instalado ya en los entornos servidor de Desarrollo y Pruebas Integradas. Sin embargo, de momento no lo voy a instalar en los entornos de Preproducción y Producción hasta dejar pasar un tiempo y poder hacer pruebas de carga. En función de los calendarios que maneje de aquí a unos meses es posible que no tenga tiempo de certificarlo y, además, tengo noticias de primera mano "desde dentro" del equipo de Hotspot acerca del calendario de siguientes actualizaciones y versiones de Hotspot incluidas en ellas... pero eso es otra historia que escribiré en otro post ;-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-8769813026826845708?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/8769813026826845708/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=8769813026826845708' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/8769813026826845708'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/8769813026826845708'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/11/lanzamiento-de-java-6u10.html' title='Lanzamiento de Java 6u10'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-8171617614272847582</id><published>2008-10-30T23:14:00.005+01:00</published><updated>2008-11-21T10:25:59.507+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='XML/SOAP'/><category scheme='http://www.blogger.com/atom/ns#' term='Glassfish/Tomcat'/><title type='text'>Fast InfoSet, Fast Web Services &amp; XML encoding rules (XER) for ASN.1</title><content type='html'>&lt;em&gt;&lt;/em&gt;&lt;br /&gt;&lt;em&gt;[Aviso para navegantes:&lt;/em&gt;&lt;br /&gt;&lt;em&gt;&lt;/em&gt;&lt;br /&gt;&lt;em&gt;A diferencia del resto de temas, en los que hablo desde el conocimiento o experiencia (o al menos desde un cierto conocimiento, tampoco vamos a ponernos chulos), sobre este tema en concreto no tengo experiencia ni he podido hacer pruebas. Se trata de una línea de investigación que abrí hace algún tiempo y que no he tenido tiempo de cerrar u ocasión/excusa por concurrencia importante en accesos a Web Services de mi proyecto...&lt;/em&gt; ]&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Curioso tema. Pongámosmos bíblicos...&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;em&gt;Al principio era el COBOL. Las estructuras eran sencillas, fáciles y rápidas de parsear, los sistemas intercambiaban ficheros con &lt;strong&gt;campos de anchura fija&lt;/strong&gt;. Y vio que era bueno...&lt;br /&gt;&lt;br /&gt;Luego llegó el C y el C++, y empezó a requerirse optimización en los tamaños de los ficheros así como en el parseo. Y llegaron los mensajes con &lt;strong&gt;campos de tamaño variable&lt;/strong&gt; en los que al comienzo de cada campo se indica la &lt;strong&gt;longitud&lt;/strong&gt; del mismo. Existieron múltiples implementaciones, quizás la más estandarizada sea el &lt;a href="http://es.wikipedia.org/wiki/ASN.1"&gt;ASN.1&lt;/a&gt; (Abstract Syntax Notation One). Tremendamente rápidos de parsear y eficientes en espacio excepto si el contenido de los campos es de tamaño pequeño en media.&lt;br /&gt;&lt;br /&gt;Luego llegó la era de Internet. De la interoperabilidad y de lo que mola. Y alguien inventó el XML que son mensajes estructurados donde los campos tienen &lt;strong&gt;delimitadores de inicio y de fin&lt;/strong&gt; para ser parseados por aplicaciones pero legibles para el humano en base al éxito del HTML. Muy mono, muy manejable, muy entendible, pero muy ineficiente tanto en tamaño como en velocidad de parseo.&lt;/em&gt;&lt;/blockquote&gt;Vamos, que como el cangrejo. Vamos hacia atrás. No se "nota mucho" porque en paralelo se ha incrementado la potencia de procesamiento y la velocidad de las redes. Pero, cuando hay intercambio exhaustivo de mensajería o saturación del ancho de banda, la solución "elegante" puede no servir.&lt;br /&gt;&lt;br /&gt;En este enlace se explica el problema de de forma más seria, pero en el fondo dicen lo mismo que yo... &lt;a href="http://java.sun.com/developer/technicalArticles/WebServices/fastWS/"&gt;http://java.sun.com/developer/technicalArticles/WebServices/fastWS/&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;em&gt;(...)&lt;br /&gt;&lt;br /&gt;XML-based messaging is at the heart of the current Web Services technology. XML's self-describing nature has significant advantages, but they come &lt;strong&gt;at the price of bandwidth and performance&lt;/strong&gt;.&lt;br /&gt;&lt;br /&gt;XML-based messages are larger and require more processing than existing protocols such as RMI, RMI/IIOP or CORBA/IIOP: data is represented inefficiently, and binding requires more computation. For example, an RMI service can perform an order of magnitude faster than an equivalent Web Service. Use of HTTP as the transport for Web Services messages is not a significant factor when compared to the binding of XML to programmatic objects.&lt;br /&gt;&lt;br /&gt;Increased bandwidth usage affects both wired and wireless networks. Often the latter, e.g. mobile telephone networks, have bandwidth restrictions allotted for communication by a network device. In addition, larger messages increase the possibility of retransmission since the smaller the message, the less likely it will be corrupted when in the air.&lt;br /&gt;&lt;br /&gt;Increased processing requirements affects network devices communicating using both types of networks (wired and wireless). A server may not be able to handle the throughput the 'network' demands of it. Mobile phone battery life may be reduced as a device uses more memory, performs more processing and spends more time transmitting information. As the scale of Web Services usage increases, these problems are likely to be exacerbated.&lt;br /&gt;&lt;/em&gt;&lt;/blockquote&gt;Y en esta línea, hace ya algunos años, se comenzaron dos iniciativas, lideró unas propuestas y especifcaciones llamadas "&lt;a href="http://java.sun.com/developer/technicalArticles/xml/fastinfoset/"&gt;Fast Infoset&lt;/a&gt;" (trabajo conjunto entre ISO/IEC JTC 1 y ITU-T) y "&lt;a href="http://java.sun.com/developer/technicalArticles/WebServices/fastWS/"&gt;Fast Web Services&lt;/a&gt;" (iniciativa de Sun Microsystems y también en proceso de estandarización por ambas organizaciones).&lt;br /&gt;&lt;br /&gt;&lt;a href="http://java.sun.com/developer/technicalArticles/WebServices/fastWS"&gt;&lt;img style="FLOAT: right; MARGIN: 0px 0px 10px 10px; CURSOR: hand" alt="" src="http://java.sun.com/developer/technicalArticles/WebServices/fastWS/Figure-1.gif" border="0" /&gt;&lt;/a&gt;Muy resumidamente y en términos mundanos significa que los mensajes y estructuras se serializan &lt;strong&gt;codificados por debajo en estructuras binarias ASN.1&lt;/strong&gt;, pero que el las partes (enviante y receptor) se tratar como si fuera XML normal y corriente. Es decir, en términos de capas OSI, los niveles de transporte y protocolo cambian, pero no cambia el nivel de aplicación.&lt;br /&gt;&lt;br /&gt;Para los que quieran más detalles, sus números de estándar son:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;ITU-T Rec. X.891 ISO/IEC 24824-1&lt;/li&gt;&lt;li&gt;ITU-T Rec. X.892 ISO/IEC 24824-2&lt;/li&gt;&lt;/ul&gt;Y, además de los enlaces que he incluido arriba (de Sun Microsystems), estas presentaciones son muy legibles:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.itu.int/ITU-T/studygroups/com17/tutorials/tutorial_2005_03_30_sandoz.pdf"&gt;http://www.itu.int/ITU-T/studygroups/com17/tutorials/tutorial_2005_03_30_sandoz.pdf&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://wiki.glassfish.java.net/attach/Presentations/FI-Encoding.pdf"&gt;http://wiki.glassfish.java.net/attach/Presentations/FI-Encoding.pdf&lt;/a&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;Y estos dos enlaces también están muy bien escritos:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://asn1.elibel.tm.fr/xml/finf.htm"&gt;Fast Infoset&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://asn1.elibel.tm.fr/xml/fws.htm"&gt;Fast Web Services&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;Y en este blog hay toda una catogría muy interesante al respecto...&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://blogs.sun.com/sandoz/category/Fast+Infoset"&gt;http://blogs.sun.com/sandoz/category/Fast+Infoset&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;strong&gt;Desde mi punto de vista el tema en si mismo es para partirse de la risa&lt;/strong&gt; (¿por qué hemos usado ASN.1 desde el principio y nos dejamos de tontadas?) y aparte, creo que esto soluciona sólo parte del problema (el transporte, aunque si usamos compresión GZIP ya ganamos bastante) pero no tiempo de computación y tratamiento. Amén de que dos no pelean si uno no quiere, es decir, ambos partners en el diálogo tienen que ser capaces de generar y entender estos Fast Web Services; si no, estamos jodidos...&lt;br /&gt;&lt;br /&gt;Bueno, y ahora las implementaciones... Pues la buena noticia es que todo esto no es sólo teoría o desarrollos de difícil integración, sino que Sun tiene una implementación Open Source dentro del paraguas de Glassfish:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Programáticamente, como se explica en &lt;a href="https://fi.dev.java.net/how-to-use.html"&gt;https://fi.dev.java.net/how-to-use.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Por configuración general, añadiendo al domain.xml el parámetro &lt;span style="font-family:courier new;"&gt;&lt;code&gt;-Dcom.sun.xml.ws.client.ContentNegotiaton=optimistic&lt;/code&gt;&lt;/span&gt;. Tengo que avisar, no obstante, que esta opción no la he encontrado en ninguna documentación oficial, sino en la presentación &lt;a href="http://wiki.glassfish.java.net/attach/GlassFishDay2008Hyderabad/GlassFishDay2008PerfPreso.pdf"&gt;http://wiki.glassfish.java.net/attach/GlassFishDay2008Hyderabad/GlassFishDay2008PerfPreso.pdf&lt;/a&gt; que ya hemos nombrado alguna que otra vez.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Si tengo tiempo de probarlo, os aviso...&lt;/p&gt;Pero no sólo de Sun vive el hombre... Al menos están estas tres implementaciones conocidas:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.noemax.com/" target="_self"&gt;FastInfoset.NET (de Noemax&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.oss.com/" target="_self"&gt;OSS Nokalva&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href="https://fi.dev.java.net/"&gt;Fast Infoset / Glassfish&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;a href="http://java.sun.com/developer/technicalArticles/xml/fastinfoset/"&gt;&lt;img style="DISPLAY: block; MARGIN: 0px auto 10px; TEXT-ALIGN: center" alt="" src="http://java.sun.com/developer/technicalArticles/xml/fastinfoset/images/fast-infoset_html_308012b8.gif" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Raro, ¿verdad?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-8171617614272847582?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/8171617614272847582/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=8171617614272847582' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/8171617614272847582'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/8171617614272847582'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/10/fast-infoset-fast-web-services-xml.html' title='Fast InfoSet, Fast Web Services &amp; XML encoding rules (XER) for ASN.1'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-1588872457653258853</id><published>2008-10-23T15:33:00.007+02:00</published><updated>2011-04-27T13:47:53.102+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JDK/JVM'/><category scheme='http://www.blogger.com/atom/ns#' term='Netbeans'/><title type='text'>Tuning de NetBeans 7.x y 6.x</title><content type='html'>&lt;em&gt;[Actualizado el 27/4/2011].&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;Otro tip de rendimiento que no tiene que ver con el entorno de explotación, sino con el entorno de desarrollo. Mejoras de rendimiento de Netbeans 6/7 a través de opciones de arranque y otros factores...&lt;br /&gt;&lt;br /&gt;¿Habéis probado a cambiar parámetros de lanzamiento del Netbeans? Pueden verse algunos tips recomendados por el propio equipo de Netbeans en:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://performance.netbeans.org/howto/jvmswitches/index.html"&gt;http://performance.netbeans.org/howto/jvmswitches/index.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://wiki.netbeans.org/wiki/view/FaqGCPauses"&gt;http://wiki.netbeans.org/wiki/view/FaqGCPauses&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://wiki.netbeans.org/ScanOnDemand"&gt;http://wiki.netbeans.org/ScanOnDemand&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://wiki.netbeans.org/FaqScanningAndIndexingPerformanceHints"&gt;http://wiki.netbeans.org/FaqScanningAndIndexingPerformanceHints&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;Yo utilizo Java 6 update 25 y tocando algunas opciones de lanzamiento "interesantes" me va bastante-bastante bien en mi portátil con Centrino Duo. Aunque en realidad, mucho más importante que todo esto, lo que más me ha ayudado a aligerar el entorno es &lt;strong&gt;cambiar de disco duro a un híbrido&lt;/strong&gt; con 4 GB de SDD y revolución a 7200 rmp (&lt;a href="http://www.seagate.com/www/es-es/products/laptops/laptop-hdd/"&gt;Seagate Momentus XT&lt;/a&gt;) así como desactivar todos los módulos y plugins que no se utilizan ni se van a utilizar, y tener cuidado de excluir las carpetas de proyectos de los scans antivirus.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;El tema del escaneo constante de cambios en proyectos sigue siendo una pequeña pesadilla, pero estoy mitigándolo con las recomendaciones que en los enlaces anteriores se indican.&lt;br /&gt;&lt;br /&gt;Mi fichero netbeans.conf contiene las siguientes opciones de lanzamiento:&lt;br /&gt;&lt;blockquote&gt;&lt;code&gt;&lt;i&gt;###[serverperformance.blogspot.com]&lt;/i&gt;&lt;br /&gt;netbeans_default_options="-J-Dcom.sun.aas.installRoot=\"C:\Java\glassfish-v2ur2\" -J-client -J-Xss2m -J-Xms32m -J-XX:PermSize=32m -J-XX:MaxPermSize=500m -J-XX:+UseConcMarkSweepGC -J-XX:+CMSClassUnloadingEnabled -J-XX:+CMSPermGenSweepingEnabled -J-Djava.index.useMemCache=true -J-Xverify:none -J-XX:+UseBiasedLocking -J-XX:+AggressiveOpts -J-Djava.net.preferIPv4Stack=true -J-Dsun.java2d.d3d=true -J-Dsun.java2d.noddraw=false -J-Dapple.laf.useScreenMenuBar=true -J-Dapple.awt.graphics.UseQuartz=true "&lt;br /&gt;&lt;/code&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-1588872457653258853?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/1588872457653258853/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=1588872457653258853' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/1588872457653258853'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/1588872457653258853'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/10/rendimiento-del-netbeans6.html' title='Tuning de NetBeans 7.x y 6.x'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-7746336261158192699</id><published>2008-10-21T00:44:00.001+02:00</published><updated>2008-10-21T00:47:07.881+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java CAPS'/><title type='text'>Rendimiento de la instalación de Java CAPS</title><content type='html'>&lt;em&gt;[Java CAPS 5.1.2 / Java CAPS 5.1.3]&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;Je, je, este no es un tip de rendimiento en tiempo de ejecución... sino un tip de rendimiento en tiempo de desarrollo, más bien en tiempo de instalación del repositorio y entorno de desarrollo...&lt;br /&gt;&lt;br /&gt;De la documentación oficial de Sun:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;3. &lt;em&gt;Some optional but recommended performance enhancements: &lt;/em&gt;&lt;ul&gt;&lt;li&gt;&lt;em&gt;Disable on-demand virus scanning on your Java CAPS installation directory. The large number of small files manipulated within the environment causes much unnecessary disk and CPU load if subject to constant scanning.&lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;Set Internet Explorer’s cache size to 64Kb to improve the upload performance when uploading SAR files to the Repository. This is described in Microsoft’s Knowledge Base Article #329781&lt;/em&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Aún con todo sigue siendo un infierno...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-7746336261158192699?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/7746336261158192699/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=7746336261158192699' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/7746336261158192699'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/7746336261158192699'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/10/rendimiento-de-la-instalacin-de-java.html' title='Rendimiento de la instalación de Java CAPS'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-2334858532437897203</id><published>2008-10-14T21:26:00.010+02:00</published><updated>2008-11-21T10:19:34.791+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='HTTP/S'/><category scheme='http://www.blogger.com/atom/ns#' term='Glassfish/Tomcat'/><title type='text'>Tuning de motor de JSP en Glassfish: Configuración para entorno de producción</title><content type='html'>Como continuación del post &lt;a href="http://serverperformance.blogspot.com/2008/09/glassfish-v2-performance-tuning-tips.html"&gt;Glassfish V2: Performance Tuning, Tips &amp;amp; Tricks&lt;/a&gt;, a continuación pego algunos parámetros óptimos para entornos productivos en Glassfish V2. Recordad que Glassfish viene configurado por defecto "para desarrollo" y que pueden hacerse unos cuantos tunings para producción.&lt;br /&gt;&lt;br /&gt;En el mencionado post están todos, amén de los parámetros generales de lanzamiento de las JVM que ya recomendé en el post &lt;a href="http://serverperformance.blogspot.com/2008/08/jvm-tunning-parmetros-de-lanzamiento-de.html"&gt;JVM tuning: Parámetros de lanzamiento de JVM: Sun Hotspot&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Esta vez toca la configuración de nuestra aplicación web, en lo que concierne al motor de JSP. Los parámetros óptimos en mi experiencia y necesidades son:&lt;br /&gt;&lt;br /&gt;[fichero sun-web.xml]: &lt;blockquote&gt;&lt;code&gt;&lt;br /&gt;(...)&lt;br /&gt;&amp;lt;jsp-config&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;property name=&lt;strong&gt;"development"&lt;/strong&gt; value=&lt;strong&gt;"false"&lt;/strong&gt;&amp;gt;&lt;br /&gt;&amp;lt;description&amp;gt;If set to true, enables development mode, which allows JSP files to be checked for modification. Specify the frequency at which JSPs are checked using the modificationTestInterval property.&amp;lt;/description&amp;gt;&lt;br /&gt;&amp;lt;/property&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;property name=&lt;strong&gt;"usePrecompiled"&lt;/strong&gt; value=&lt;strong&gt;"true"&lt;/strong&gt;&amp;gt;&lt;br /&gt;&amp;lt;description&amp;gt;&lt;br /&gt;If set to true, an accessed JSP ile is not compiled. Its precompiled servlet class is used instead. It is assumed that JSP files have been precompiled, and their corresponding servlet classes have been bundled in the web application’s WEB-INF/lib or WEB-INF/classes directory.&amp;lt;/description&amp;gt;&lt;br /&gt;&lt;em&gt;¡¡¡OJO!!!! Si se pone a true, hay que compilarlos a mano con jspc y dejarlos en el directorio indicado. En nuestro caso, lo ponemos a false pero al desplegar la aplicación en el servidor de aplicaciones, marcamos el check "Precompile JSP" en la consola, para que se haga en ese momento...&lt;/em&gt;&lt;br /&gt;&amp;lt;/description&amp;gt;&lt;br /&gt;&amp;lt;/property&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;property name=&lt;strong&gt;"mappedfile"&lt;/strong&gt; value=&lt;strong&gt;"false"&lt;/strong&gt;&amp;gt;&lt;br /&gt;&amp;lt;description&amp;gt;If set to true, generates static content with one print statement per input line, to ease debugging.&amp;lt;/description&amp;gt;&lt;br /&gt;&amp;lt;/property&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;property name=&lt;strong&gt;"suppressSmap"&lt;/strong&gt; value=&lt;strong&gt;"true"&lt;/strong&gt;&amp;gt;&lt;br /&gt;&amp;lt;description&amp;gt;If set to true, generation of SMAP information for JSR 45 debugging is suppressed.&amp;lt;/description&amp;gt;&lt;br /&gt;&amp;lt;/property&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;property name=&lt;strong&gt;"fork"&lt;/strong&gt; value=&lt;strong&gt;"false"&lt;/strong&gt;&amp;gt;&lt;br /&gt;&amp;lt;description&amp;gt;Specifies that Ant forks the compiling of JSP files, using a JVM machine separate from the one in which Tomcat is running.&amp;lt;/description&amp;gt;&lt;br /&gt;&amp;lt;/property&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;property name=&lt;strong&gt;"classdebuginfo"&lt;/strong&gt; value=&lt;strong&gt;"false"&lt;/strong&gt;&amp;gt;&lt;br /&gt;&amp;lt;description&amp;gt;Specifies whether the generated Java servlets are compiled with the debug option set (-g for javac).&amp;lt;/description&amp;gt;&lt;br /&gt;&amp;lt;/property&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;property name=&lt;strong&gt;"xpoweredBy"&lt;/strong&gt; value=&lt;strong&gt;"false"&lt;/strong&gt;&amp;gt;&lt;br /&gt;&amp;lt;description&amp;gt;If set to true, the X-Powered-By response header is added by the generated servlet. &lt;em&gt;Buena idea para ocultar el AS por motivos de seguridad&lt;/em&gt;&amp;lt;/description&amp;gt;&lt;br /&gt;&amp;lt;/property&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;property name=&lt;strong&gt;"keepgenerated"&lt;/strong&gt; value=&lt;strong&gt;"true"&lt;/strong&gt;&amp;gt;&lt;br /&gt;&amp;lt;description&amp;gt;If set to true, keeps the generated Java files. If false, deletes the Java files.&amp;lt;/description&amp;gt;&lt;br /&gt;&amp;lt;/property&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/jsp-config&amp;gt;&lt;br /&gt;(...)&lt;br /&gt;&lt;/code&gt;&lt;/blockquote&gt;&lt;br /&gt;Ni que decir tiene que estos los fuerzo así porque sus valores por defecto son los contrarios. Para más información no seas vago y abre los PDF de la documentación...&lt;br /&gt;&lt;br /&gt;Nota: me extrañaría mucho que estas mismas opciones no funcionaran "tal cual" en Tomcat 5.5 y superiores... Por cierto que todavía no me queda claro si GF tiene un Tomcat dentro, si está inspirado en Tomcat, o si simplemente han respetado las propiedades de configuración para eliminar resistencias al cambio... :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-2334858532437897203?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/2334858532437897203/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=2334858532437897203' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/2334858532437897203'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/2334858532437897203'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/10/tuning-de-motor-de-jsp-en-glassfish.html' title='Tuning de motor de JSP en Glassfish: Configuración para entorno de producción'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-5142269154821080663</id><published>2008-10-07T15:44:00.005+02:00</published><updated>2008-11-21T10:26:49.255+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JMS'/><category scheme='http://www.blogger.com/atom/ns#' term='Java CAPS'/><title type='text'>Cuidado con XA y JMS (o "Estoy hasta los huevos desde hace años")</title><content type='html'>Pues lo de casi siempre:&lt;br /&gt;&lt;br /&gt;...mucha capa de abstracción, mucha transparecia para el desarrollador y mucha magia... y a la hora de la verdad hay que remangarse y entenderlo todo.&lt;br /&gt;&lt;br /&gt;Porque en Java CAPS las colaboraciones que interactúan dentro de un conectivity map en el fondo son MDBs. Y los MDBs en el fondo son EJB disparados por colas JMS. Y por defecto las transacciones JMS son XA, &lt;strong&gt;con dos cojones&lt;/strong&gt;.&lt;br /&gt;&lt;br /&gt;Es decir: si tengo unas cuantas colaboraciones (en Java CAPS, léase "unos cuantos EJBs" para una visión más generalista del mismo problema) que interactúan "desacopladamente" entre si (¡qué gran palabra! casi a la altura de "sinergia" y de "talento"...), o un master que va lanzando colaboraciones/MDBs de forma asíncrona o síncrona (request/reply), parece lógico pensar que todos los recursos a los que se accedan estén en modo XA... al menos, si no pensamos, los declaramos así :-)&lt;br /&gt;&lt;br /&gt;Nota: el objetivo de este artículo no es explicar el patrón request/reply, pero ahí dejo un diagrama ilustrativo (enlaza con la explicación del patrón en docs.sun.com):&lt;br /&gt;&lt;a href="http://docs.sun.com/source/819-2574/prog_model.html#wp30292/"&gt;&lt;img style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://docs.sun.com/source/819-2574/images/to_ReplyTo5.gif" border="0" /&gt;&lt;/a&gt;Ya primera gran mentira viene ahí, porque en el 99% de los casos no sólo accedemos a bases de datos sino que también escribimos en logs o en ficheros a disco, o interactuamos con un monitor transaccional o hacemos una petición http o TCP cruda... Llevo más de 6 años sin ver dónde está la magia del XA y viendo sólo dolores de cabeza, pero todo esto es otra cuestión...&lt;br /&gt;&lt;br /&gt;...Lo que viene al caso para este artículo es que si en una colaboración Java CAPS (o en un MDB normal si funcionamos fuera de un integrador) invocamos a base de datos con transacciones XA y la invocación JMS a ese componente estaba también en modo XA, se produce un &lt;em&gt;deadlock: &lt;/em&gt;como la inserción/modificación falla, el sistema decide deshacer también el envío a la cola JMS y por supuesto no llega nunca a enviar el mensaje de respuesta a la colaboración maestra indicándole el fallo (para que desde ahí se reaccione o lo que sea); en lugar de eso, la invocación al segundo componente vuelve a dispararse porque la cola estaba en modo XA. Y vuelve a fallar la inserción. Y así indefinidamente.&lt;br /&gt;&lt;br /&gt;Esto que he explicado fatal está perfectamente explicado en el siguiente artículo: &lt;a href="http://blogs.sun.com/fkieviet/entry/request_reply_from_an_ejb"&gt;http://blogs.sun.com/fkieviet/entry/request_reply_from_an_ejb&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;La solución: &lt;strong&gt;en modelos síncronos (request/reply) nunca usar modo XA&lt;/strong&gt; para el envío del mensaje de request, sino ponerlo a modo TRANSACTED. Y ya que estamos, si sólo interactuamos con una instancia de base de datos, el recurso JNDI tampoco lo definamos en modo XA sino normal. Manténgase en modo XA sólo las invocaciones asíncronas de verdad y si queremos evitar posibles duplicados en inserciones. Pero mi apuesta es por no usar XA para nada y gestioanr las cosas a mano: porque teniendo el control, tendremos toda la capacidad de reacción con incidencias en el entorno productivo en lugar de liarnos a intentar modelizar mentalmente qué narices está pasando.&lt;br /&gt;&lt;br /&gt;Porque además, en nuestro caso, hemos ganado un 50% de rendimiento en algunos pasos y el servidor de aplicaciones va mucho más ligero y con menos sobrecarga de recursos y cosas raras... (¿no iba este blog sobre rendimiento?).&lt;br /&gt;&lt;br /&gt;Como digo, véase el artículo referenciado (no habla de Java CAPS en particular sino de EJB y JMS en general): &lt;a href="http://blogs.sun.com/fkieviet/entry/request_reply_from_an_ejb"&gt;http://blogs.sun.com/fkieviet/entry/request_reply_from_an_ejb&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Ciao ciao&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-5142269154821080663?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/5142269154821080663/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=5142269154821080663' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/5142269154821080663'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/5142269154821080663'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/10/cuidado-con-xa-y-jms-o-estoy-hasta-los.html' title='Cuidado con XA y JMS (o &quot;Estoy hasta los huevos desde hace años&quot;)'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-3749681284630132978</id><published>2008-10-01T15:26:00.011+02:00</published><updated>2008-11-21T10:31:09.310+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Strings/Buffers/Ficheros'/><category scheme='http://www.blogger.com/atom/ns#' term='JDK/JVM'/><title type='text'>Propuestas de optimizaciones para Strings</title><content type='html'>&lt;a href="http://4.bp.blogspot.com/_4ZEuwiCuF6A/SONdp9PHAOI/AAAAAAAAAGE/352rC09ban4/s1600-h/bici_paraigues%5B1%5D.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5252144565838086370" style="FLOAT: right; MARGIN: 0px 0px 10px 10px" alt="" src="http://4.bp.blogspot.com/_4ZEuwiCuF6A/SONdp9PHAOI/AAAAAAAAAGE/352rC09ban4/s200/bici_paraigues%5B1%5D.jpg" border="0" /&gt;&lt;/a&gt; Al hilo de lo comentado en los posts &lt;a href="http://serverperformance.blogspot.com/2008/09/copy-on-write-optimization-for.html"&gt;Copy-on-write optimization for StringBuilder and StringBuffer&lt;/a&gt; y &lt;a href="http://serverperformance.blogspot.com/2008/09/copy-on-write-optimization-for_06.html"&gt;Copy-on-write optimization for StringBuilder and StringBuffer (II)&lt;/a&gt;, he estado trabajando más de la mitad del mes de septiembre (robándole tiempo a mi mujer, al sueño y a la tele por se orden) en una idea que yo pensaba que era cojonuda, aunque aviso de antemano que probablemente no sea buena, vistos los comentarios y estadísticas recogidas por mi... :-(&lt;br /&gt;&lt;br /&gt;Por cierto, antes de seguir leyendo, si no estás familiarizado con cómo están implementados los StringBuilders y StringBuffer en el JDK, échale un vistazo a esos fuentes y al Java Language Specifications, porque si no esto pierde todo su encanto. En general es una buena práctica revisar cómo la gente del JDK ha hecho ciertas cosas, yo he aprendido de ellos mucho-mucho en los últimos 11 años... al menos demuestra algo de interés por el tema :-)&lt;br /&gt;&lt;br /&gt;La nueva idea básicamente consiste en intentar ver la creación de Strings desde una perspectiva nueva: si el 95% de las operaciones sobre un StringBuilder son appends (y no inserts, deletes, etc), quizás eso nos puede dar una pista de reimplementación basada en almacenar la lista de cadenas que se quieren concatenar y sólo hacer la concatenación efectiva al invocar al método toString().&lt;br /&gt;&lt;br /&gt;Desde el punto de vista teórico supone una ventaja importante frente al modelo actual de StringBuilder ya que no es necesario crear un array de chars interno, una vez llenado crear otro más grande y copiar los contenidos de uno a otro, y finalmente volver a hacer una creación de array de chars con el tamaño exacto y copia de los caracteres allí, en el toString().&lt;br /&gt;&lt;br /&gt;Después de muchas vueltas y muchos intentos y benchmarkings, mi propuesta pasaba por crear una clase &lt;span style="font-family:courier new;"&gt;java.lang.StringAppender&lt;/span&gt;, que contiene internamente una lista de Strings...&lt;br /&gt;&lt;br /&gt;El principal problema es con la inserción de un sólo carácter, operación que es tremendamente frecuente a la vista de las pruebas. Mi solución es entre un 5 y un 160% mejor al concatenar Strings, pero más de un 100% peor al concatenar chars individualmente. Como digo he probado otras combinaciones (almacenar char[][], almacenar dos listas, una para Strings y otra para chars, modificar StringBuilder para que pueda funcionar en "fast mode" y "normal mode" según interese... pero la opción más limpia y de mejor rendimiento en los casos que son típicos en un desarrollador de aplicaciones web (y que yo suponía que esto era extrapolable a cualquier otro desarrollo, incluyendo el del JDK, Netbeans, etc), es la que adjunto.&lt;br /&gt;&lt;br /&gt;Pero no es suficiente, o al menos sería difícil de justificar el cambio de API (que es algo que no gusta mucho, evidentemente)...&lt;br /&gt;&lt;br /&gt;En el archivo de la lista de correo de desarrollo de las librerías de núcleo para JDK 7 puede verse el detalle completo, las distintas respuestas públicas (también hubo unos cuantos consejos "privados"), y descargar el código fuente tanto en los cambios a String.java propuestos como la nueva clase StringAppender.java (nota: si hay interés en descargarlo, tómese la última versión publicada, no la primera)... así que no me enrollaré mucho más.&lt;br /&gt;&lt;br /&gt;Ahí dejo el enlace al thread: &lt;a href="http://mail.openjdk.java.net/pipermail/core-libs-dev/2008-September/000734.html"&gt;http://mail.openjdk.java.net/pipermail/core-libs-dev/2008-September/000734.html&lt;/a&gt;. Y esta es la copia literal de mi primer y mi tercer mensaje que son un resumen ejecutivo de la idea, las estadísticas y las conclusiones.&lt;br /&gt;&lt;br /&gt;El primer mensaje a la lista (&lt;a href="http://mail.openjdk.java.net/pipermail/core-libs-dev/2008-September/000734.html"&gt;&lt;strong&gt;http://mail.openjdk.java.net/pipermail/core-libs-dev/2008-September/000734.html&lt;/strong&gt;&lt;/a&gt;):&lt;br /&gt;&lt;blockquote&gt;&lt;p&gt;&lt;em&gt;(...) &lt;/em&gt;&lt;em&gt;This is my proposal to be discussed:&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;&lt;br /&gt;&lt;/em&gt;&lt;/p&gt;&lt;em&gt;&lt;/em&gt;&lt;em&gt;&lt;strong&gt;THE GOAL:&lt;/strong&gt;&lt;/em&gt; &lt;p&gt;&lt;em&gt;Boost the overall String concatenation / append operations. &lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;&lt;br /&gt;&lt;strong&gt;BACKGROUND / HISTORY:&lt;/strong&gt;&lt;/em&gt;&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;em&gt;At the beginning (JDK 1.0 days) we had String.concat() and StringBuffer to build Strings. Both approaches had initially bad performance.&lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;Starting at JDK 1.4 (I think), a share-on-copy strategy was introduced in StringBuffer. The performance gain was obvious, but increased the needed heap and in some cases produced some memory leak when reusing StringBuffer.&lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;Starting at JDK 1.5, StringBuilder was introduced as the “unsyncronized version”, but also the copy-on-write optimization was undo, becoming an "always copy" scenario. Also, the String + operator is translated to StringBuilder.append() by javac. This has been discussed but no better alternative was found (see&lt;/em&gt;&lt;a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6219959"&gt;&lt;em&gt;http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6219959&lt;/em&gt;&lt;/a&gt;&lt;em&gt; ).&lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;This current implementation generates several System.arraycopy() calls: at least one per append/insert/delete (two if expanding capacity)... and a final one in the toString() method! &lt;/em&gt;&lt;/li&gt;&lt;/ul&gt;&lt;em&gt;&lt;/em&gt;&lt;p&gt;&lt;em&gt;&lt;br /&gt;&lt;strong&gt;STUDYING THE USES:&lt;/strong&gt;&lt;br /&gt;&lt;/em&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;em&gt;If we look at the uses of StringBuilder (both inside JDK code, in application servers and/or final applications), in nearly 99% of times it is only used to create a String in a single-threaded context and (the most important fact) only using the append() and toString() methods.&lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;Also, only in 5% of the instantiatings, the coder establishes the initial capacity. Many times doesn’t matter, but other times it is impossible to guess it or calculate it. And even worst: some times the coder fails in his guess: establishes to much initial capacity or too few. &lt;/em&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;em&gt;&lt;br /&gt;&lt;strong&gt;MY PROPOSAL:&lt;/strong&gt;&lt;br /&gt;&lt;/em&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;em&gt;Create a new class &lt;span style="font-family:courier new;"&gt;java.lang.StringAppender implements Appendable&lt;/span&gt;. &lt;/em&gt;&lt;/li&gt;&lt;ol&gt;&lt;li&gt;&lt;em&gt;Mostly same in its exposed public constructors and methods than StringBuilder, but the only operations are the “append()” ones (no insert, no delete, no replace).&lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;Internally represented as a String array.&lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;Only arraycopy() or create char arrays once, inside the toString() method (well, this isn’t completely true: also arraycopies when appending objects/variables other than String instances or char arrays, but the most typical operation is appending strings!).&lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;Doesn’t need to stablish an initial capacity. Never more calculating it or guessing it.&lt;/em&gt;&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;&lt;em&gt;Add a new constructor in the &lt;span style="font-family:courier new;"&gt;java.lang.String&lt;/span&gt; class (actually 5 new constructors for performance reasons, see below): &lt;/em&gt;&lt;/li&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-family:courier new;"&gt;&lt;em&gt;public String(String... strs)&lt;/em&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;"&gt;&lt;em&gt;public String(String str0, String str1)&lt;/em&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;"&gt;&lt;em&gt;public String(String str0, String str1, String str2)&lt;/em&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;"&gt;&lt;em&gt;public String(String str0, String str1, String str2, String str3)&lt;/em&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;&lt;em&gt;(NOTE: these 3 additional constructors are needed to boost appends of a small number of Strings, in which case the overload of creating the array and then looping inside is much greater than passing 2, 3 or 4 parameters in the constructor invocation).&lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;Change the javac behavior: the String + operator must be translated into“&lt;span style="font-family:courier new;"&gt;new String(String...);&lt;/span&gt;” &lt;span style="font-size:100%;"&gt;instead &lt;/span&gt;of into “&lt;span style="font-family:courier new;"&gt;new StringBuilder().append().append()... ..toString();&lt;/span&gt;”.&lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;Revise other JDK sourcecodes to use StringAppender, and the rest of programs all around the world. (By the way in the Glassfish V2 sourcecode I see several String.concat() invocations; seems strange to me... ). &lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;So the new blueprints for String concatenation should be: &lt;/em&gt;&lt;/li&gt;&lt;ol&gt;&lt;li&gt;&lt;em&gt;For append-only, not conditional String concatenations, use the new String constructor. Example: &lt;span style="font-family:courier new;"&gt;String result = new String(part1, part2, part3,part4);&lt;/span&gt;&lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;For append-only, conditional or looped concatenations, or for appending other Objects/types, use the StringAppender class.&lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;For other manipulations (insert, delete, replace), use StringBuilder.&lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;For a thread-safe version, use StringBuffer.&lt;/em&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/ul&gt;&lt;p&gt;&lt;em&gt;&lt;br /&gt;&lt;strong&gt;THE BOOST:&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;As you can see in my microbenchmark results, executed in Linux x64 and Windows 32 bits (-server, -client, and -XX:+AggressiveOpts versions), we can achieve a boost between 1% and 167% (depends on the scenario and architecture). Well, those values are the extremes, the typical gains go between 20% and 70%. I think these results are good enough to be taken intoconsideration :-) &lt;/em&gt;&lt;/p&gt;&lt;em&gt;&lt;br /&gt;&lt;/em&gt;&lt;p&gt;&lt;em&gt;&lt;strong&gt;THE SOURCE CODE:&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;See attachments, &lt;span style="font-family:courier new;"&gt;String.java.diff&lt;/span&gt; with the added code (it is clear), and &lt;span style="font-family:courier new;"&gt;StringAppender.java&lt;/span&gt; with the new proposed class. &lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;&lt;br /&gt;&lt;strong&gt;THE MICROBENCHMARK CODE:&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;See attachment. Of course should be revised. I think I have made it correctly. &lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;&lt;br /&gt;&lt;strong&gt;THE MICROBENCHMARK RESULTS &lt;/strong&gt;(varied to me about +/-1% in different executions due to the host load or whatever):&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;See attached file. I think they are great... &lt;/em&gt;&lt;/p&gt;&lt;em&gt;&lt;br /&gt;&lt;/em&gt;&lt;p&gt;&lt;em&gt;What do you think?&lt;/em&gt;&lt;br /&gt;&lt;em&gt;Best regards,&lt;/em&gt;&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Y este ha sido de momento :-) mi último mail de respuesta (&lt;a href="http://mail.openjdk.java.net/pipermail/core-libs-dev/2008-September/000747.html"&gt;&lt;strong&gt;http://mail.openjdk.java.net/pipermail/core-libs-dev/2008-September/000747.html&lt;/strong&gt;&lt;/a&gt;)...&lt;br /&gt;&lt;blockquote&gt;&lt;p&gt;&lt;em&gt;Hi all.&lt;br /&gt;&lt;br /&gt;I have measured the number of AbstractStringBuilder method invocations when executing NetBeans 6 (and making some work for 5 minutes) and when executing for a while a Glassfish V2 with a typical web application (Struts+Spring+Hibernate). These are the interesting and empirical results:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_4ZEuwiCuF6A/SONiEmS72sI/AAAAAAAAAGU/FaQ3fw_h_E8/s1600-h/stats_glassfish.gif"&gt;&lt;img id="BLOGGER_PHOTO_ID_5252149421583096514" style="DISPLAY: block; MARGIN: 0px auto 10px; TEXT-ALIGN: center" alt="" src="http://3.bp.blogspot.com/_4ZEuwiCuF6A/SONiEmS72sI/AAAAAAAAAGU/FaQ3fw_h_E8/s400/stats_glassfish.gif" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_4ZEuwiCuF6A/SONiEmdV7vI/AAAAAAAAAGc/tcXMhIUIen8/s1600-h/stats_netbeans.gif"&gt;&lt;img id="BLOGGER_PHOTO_ID_5252149421626748658" style="DISPLAY: block; MARGIN: 0px auto 10px; TEXT-ALIGN: center" alt="" src="http://1.bp.blogspot.com/_4ZEuwiCuF6A/SONiEmdV7vI/AAAAAAAAAGc/tcXMhIUIen8/s400/stats_netbeans.gif" border="0" /&gt;&lt;/a&gt;&lt;strong&gt;My conclusions: &lt;/strong&gt;&lt;br /&gt;&lt;/em&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;em&gt;The number of append(char) is bigger than append(String) and much bigger than other inserts (mainly in the Netbeans execution), so my StringAppender approach wouldn't perform good as predicted by Rémi and others. But the number of append(int), append(float), append(Boolean) is very low.&lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;In a very few situations a Builder/Buffer is reutilized after calling toString().&lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;&lt;strong&gt;expandCapacity() is invoked a lot of times!!!&lt;/strong&gt;&lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;Other operations (different than appends) are invoked a very few times.&lt;/em&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;em&gt;So I suppose that my two proposals have few sense in general (haven't they?), but maybe these figures can help to reconsider the value of the default buffer length or can help others trying to make String/StringBuilder faster. &lt;span style="FONT-WEIGHT: bold"&gt;Heap allocation and System.arraycopy calls must be reduced anyway!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;P.S: Nevertheless I attach the "final" version of my modification to String.java and of StringAppender.java, which has some optimizations to append(char) but not sufficient... I think.&lt;br /&gt;&lt;br /&gt;Best regards,&lt;br /&gt;&lt;/em&gt;&lt;/p&gt;&lt;em&gt;&lt;/em&gt;&lt;/blockquote&gt;&lt;br /&gt;A mi personalmente &lt;strong&gt;me frustra&lt;/strong&gt; la cantidad de alojamientos de heap y copias de arrays que podrían ser innecesarios en muchos casos, pero parece complejo encontrar una solución más eficiente... Bueno, en realidad tampoco es que se trate de un desastre absoluto porque afortunadamente los arraycopys están muy optimizados al menos en Solaris, Linux y Windows (me consta que ha habido mucho trabajao conjunto de los ingenieros de Sun con los de Intel y los de AMD)...&lt;br /&gt;&lt;br /&gt;Y por otro lado la solución (sea la que sea) tiene que ser una solución "universal" en el sentido de que el código se migre mayoritariamente desde StringBuilder a StringAppender (o mejor, optimizando StringBuilder claro), como pasó en la migración masiva de StringBuffer a StringBuilder en los tiempos de la 1.5... o si no nuestro querido Hotspot puede decidir no compilar nativamente todos los sus métodos (qué asco, pero esa historia y lo chulos que son los compiladores nativos de verdad merece un post aparte).&lt;br /&gt;&lt;br /&gt;Es decir, la mencionada nueva clase podría también crearse en Apache Commons o dentro de mis proyectos, pero si se usa millones de veces StringBuilder, malamente la JVM va a pensar que StringAppender tiene sus "hotspots"...&lt;br /&gt;&lt;br /&gt;Por cierto que hay otras inciativas de optimizar las clases AbstractStringBuilder, StringBuilder y StringBuffer, pero van en otra línea más de inlinings y esos rollos. Y en alguna de ellas voy a echar una mano en pruebas microbenchmarkings, si sale algo positivo ya os contaré...&lt;br /&gt;&lt;br /&gt;Y vosotros ¿qué opináis? ¿o soy yo el único que le ve interés a este asunto del rendimiento de los Strings????&lt;br /&gt;&lt;br /&gt;:-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-3749681284630132978?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/3749681284630132978/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=3749681284630132978' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/3749681284630132978'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/3749681284630132978'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/10/propuestas-de-optimizaciones-para.html' title='Propuestas de optimizaciones para Strings'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_4ZEuwiCuF6A/SONdp9PHAOI/AAAAAAAAAGE/352rC09ban4/s72-c/bici_paraigues%5B1%5D.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-5522987877302013104</id><published>2008-09-26T05:51:00.001+02:00</published><updated>2008-11-21T10:20:13.665+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JDBC/Oracle'/><title type='text'>Oracle: modo "Servidor Dedicado"</title><content type='html'>Para los "listillos" en Oracle, como yo. Es decir aquellos que no somos DBA sino que nuestra experiencia se basa más en Java, pero que nos ha tocado alguna vez configurar Oracle.&lt;br /&gt;&lt;br /&gt;Y claro, es un mundo. Y claro, las opciones aparentemente más lógicas no son las mejores.&lt;br /&gt;&lt;br /&gt;En concreto me ha pasado con la configuración de Shared/Dedicated Server. En las instrucciones de creación de base de datos dice lo siguiente: &lt;ul&gt;&lt;li&gt;&lt;strong&gt;Modo Servidor Dedicado&lt;/strong&gt;: &lt;em&gt;"para cada conexión cliente la base de datos asignará un recurso exclusivo (...). Utilice este modo cuando el número total previsto de conexiones cliente sea pequeño o los cuando los clientes realicen solicitudes reiteradas y de larga duración a la base de datos. (...)"&lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Modo Servidor Compartido&lt;/strong&gt;: &lt;em&gt;"varias conexiones cliente comparten un pool de recursos (...). Utilice este modo cuando el número de usuarios que dan conectarse simultáneamente a la base de datos sea considerable a la vez que se utilizan eficazmente los recursos del sistema. (...)"&lt;/em&gt;&lt;/li&gt;&lt;/ul&gt;A priori, ¿cuál eligiríais? Pues no.&lt;br /&gt;&lt;br /&gt;La cuestión es qué se considera "pequeño" en cuanto al número de conexiones. Y qué hardware tenemos. Y si el servidor Oracle compite por recursos con otros procesos importantes en la misma máquina. Y cómo se conectan las aplicaciones a la base de datos.&lt;br /&gt;&lt;br /&gt;En resumidas cuentas, el modo compartido es un pool de conexiones. Pero nuestras aplicaciones (Java o lo que sea) ya gestionan las conexiones a través de uno o varios pooles por lo que lo único que estamos haciendo es anidar pooles. O lo que es lo mismo, en realidad en un escenario como el mío estoy tirando recursos y rendimiento a la basura. Cada shared server consume unos 20 megas de memoria adicional y, al fin y al cabo, termina abiendo conexiones reales dedicadas, claro.&lt;br /&gt;&lt;br /&gt;Esquema del modo dedicado (Dedicated):&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_4ZEuwiCuF6A/SLu_KYKVFdI/AAAAAAAAAFA/VASTmCf9wHw/s1600-h/dedicated.gif"&gt;&lt;img id="BLOGGER_PHOTO_ID_5240992776381076946" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://4.bp.blogspot.com/_4ZEuwiCuF6A/SLu_KYKVFdI/AAAAAAAAAFA/VASTmCf9wHw/s400/dedicated.gif" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Esqueña del modo compartido (Shared Servers):&lt;br /&gt;&lt;div&gt;&lt;a href="http://3.bp.blogspot.com/_4ZEuwiCuF6A/SLu_G3oKQyI/AAAAAAAAAE4/0aYVzefwOKk/s1600-h/shared.gif"&gt;&lt;img id="BLOGGER_PHOTO_ID_5240992716108219170" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://3.bp.blogspot.com/_4ZEuwiCuF6A/SLu_G3oKQyI/AAAAAAAAAE4/0aYVzefwOKk/s400/shared.gif" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Por regla general podemos considerar que si vamos a tener menos de 500-600 sesiones abiertas y además hay pooles de conexiones en los servidores de aplicaciones cliente, se use el Modo Dedicado. En caso de un volumen mucho mayor el modo compartido.&lt;br /&gt;&lt;br /&gt;¿Y cómo cambiar de un modo compartido a uno dedicado?. En Oracle 10g y superiores: &lt;blockquote&gt;&lt;code&gt;$ sqlplus system as sys dba&lt;br /&gt;SQL&gt; alter system set processes=400 scope=spfile;&lt;br /&gt;SQL&gt; alter system reset sessions scope=spfile;&lt;br /&gt;SQL&gt; alter system set shared_servers=0 scope=spfile;&lt;br /&gt;SQL&gt; alter system set max_shared_servers=0 scope=spfile;&lt;br /&gt;SQL&gt; alter system reset dispatchers scope=spfile;&lt;/code&gt;&lt;/blockquote&gt;Donde dice "400", establézcase el valor que corresponda. Si no se establece valor para sessions, el sistema lo tomará de la siguiente fórmula: sessions = (processes * 1.1) + 5.&lt;br /&gt;&lt;br /&gt;Puesto que estos valores son estáticos, debe reiniciarse la instancia para que tome su valor.&lt;br /&gt;&lt;br /&gt;¿Y cómo se consultan los valores actuales?: &lt;blockquote&gt;&lt;code&gt;SQL&gt; show parameter [parametro]&lt;/code&gt;&lt;/blockquote&gt;P.D: Para los que conocen el init.ora y no los SPFILES, las cosas han cambiado, ahora los parámetros se establecen a través de estos comandos de sistema... &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-5522987877302013104?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/5522987877302013104/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=5522987877302013104' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/5522987877302013104'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/5522987877302013104'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/09/oracle-modo-servidor-dedicado.html' title='Oracle: modo &quot;Servidor Dedicado&quot;'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_4ZEuwiCuF6A/SLu_KYKVFdI/AAAAAAAAAFA/VASTmCf9wHw/s72-c/dedicated.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-3461081836314238262</id><published>2008-09-21T15:18:00.002+02:00</published><updated>2008-11-21T10:28:15.476+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JDK/JVM'/><title type='text'>6u6-p: Pues en Linux x64 peta!!!!!!!</title><content type='html'>&lt;em&gt;[Actualizado el 8/11/2008: El problema radica en un bug en el Escape Analisys, para más información ver &lt;/em&gt;&lt;a href="http://serverperformance.blogspot.com/2008/11/identificacin-de-bugs-en-la-versin-6u6p.html"&gt;&lt;em&gt;Identificación de bugs en la versión 6u6p y workaround&lt;/em&gt;&lt;/a&gt;&lt;em&gt; ]&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;Actualización al post &lt;a href="http://serverperformance.blogspot.com/2008/08/java-se-6u6-p-performance-release-ya.html"&gt;Java SE 6u6-p Performance Release - YA DISPONIBLE EN OTRAS PLATAFORMAS&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;Al lanzar Glassfish, mientras se despliegan mis aplicaciones (gordas eso sí), aproximadamente en el 70% de las ocasiones se me ha producido un core con un correspondiente fichero de err_&lt;xxx&gt;.log. Lo curioso es que en el 30% restante de las veces ya no se cae, aunque pase pruebas de stress... Lo he probado tanto en CentOS 5.1 sobre un Supermicro como en un Redhat ES sobre un Sun Fire x64 y en ambos ocurre lo mismo.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_4ZEuwiCuF6A/SNJA9e61FYI/AAAAAAAAAF8/mEqh6iaVmeQ/s1600-h/toma_coredump.png"&gt;&lt;img id="BLOGGER_PHOTO_ID_5247327940856059266" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://3.bp.blogspot.com/_4ZEuwiCuF6A/SNJA9e61FYI/AAAAAAAAAF8/mEqh6iaVmeQ/s400/toma_coredump.png" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;He reportado la incidencia y los ingenieros de Sun están en contacto conmigo par resolverla... pero vamos, me ha dejado el asunto un poco frío porque en la propia web de Sun dice que la versión puede ser utilizada en producción y que puedes pedir soporte. Vamos, que en ningún momento tenía la sensación de que fuera a hacer de beta-tester, aunque lo hago bien a gusto. Digo esto como una crítica "suave", porque todos los del gremio estamos expuestos a estos fallos...&lt;br /&gt;&lt;br /&gt;Pero nuestro gozo en un pozo de momento. Así que volvemos a la confortable versión 1.6.0_07...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-3461081836314238262?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/3461081836314238262/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=3461081836314238262' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/3461081836314238262'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/3461081836314238262'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/09/6u6-p-pues-en-linux-x64-peta.html' title='6u6-p: Pues en Linux x64 peta!!!!!!!'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_4ZEuwiCuF6A/SNJA9e61FYI/AAAAAAAAAF8/mEqh6iaVmeQ/s72-c/toma_coredump.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-3099662114872299499</id><published>2008-09-16T09:43:00.007+02:00</published><updated>2008-11-21T10:24:46.703+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='HTTP/S'/><category scheme='http://www.blogger.com/atom/ns#' term='General'/><category scheme='http://www.blogger.com/atom/ns#' term='Criptografía/HSM'/><category scheme='http://www.blogger.com/atom/ns#' term='Apache'/><category scheme='http://www.blogger.com/atom/ns#' term='GZIP'/><title type='text'>Aceleradores hardware</title><content type='html'>&lt;em&gt;[Nota: en este artículo hago publicidad de marcas y modelos que conozco, sin otro ánimo que el ilustrativo y en ningún caso quiere decir que alternativas de la competencia sean peores opciones].&lt;br /&gt;&lt;br /&gt;Actualizado el 19/9/2008&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;Con los avances en paralelización y multithreading de los últimos años (aunque con un cierto estancamiento de la velocidad por core), actualmente los responsables de servicios podemos adquirir servidores muy potentes a un coste relativamente bajo si lo comparamos con años anteriores. Ejemplos como &lt;a href="http://www.supermicro.com/products/system/"&gt;Supermicro&lt;/a&gt; dan opciones muy económicas para entornos de "no tan misión crítica", pero fabricantes como HP e incluso Sun dan opciones x64 tremendamente interesantes (donde sube el precio es en el soporte).&lt;br /&gt;&lt;br /&gt;En cualquier caso, hay situaciones que requieren "algo más". Y me explico. Si tenemos un entorno web de mucha concurrencia y computacionalmente "denso" puede ser que con un crecimiento horizontal en granja no sea suficiente. O mejor dicho, para mi gusto hay otras opciones que no requieren incrementar el número de máquinas.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_4ZEuwiCuF6A/SK6kNagMm1I/AAAAAAAAAEw/vTxtwnTt2DA/s1600-h/aceleradoras.png"&gt;&lt;img id="BLOGGER_PHOTO_ID_5237303967038085970" style="FLOAT: right; MARGIN: 0px 0px 10px 10px; CURSOR: hand" alt="" src="http://2.bp.blogspot.com/_4ZEuwiCuF6A/SK6kNagMm1I/AAAAAAAAAEw/vTxtwnTt2DA/s400/aceleradoras.png" border="0" /&gt;&lt;/a&gt;Me estoy refiriendo a los aceleradores hardware. Los principales usos son la aceleración de SSL (operaciones de criptografía simétrica y asimétrica específicas para comunicaciones), HSM (operaciones criptográficas de propósito general) y GZIP (para la compresión de contenidos como se menciona en el post &lt;a href="http://serverperformance.blogspot.com/2008/05/compresin-http.html"&gt;Compresión HTTP&lt;/a&gt;). He visto en una gran entidad financiera, con mis propios ojos, "morirse" un pedazo de servidor cuando hacía las operaciones SSL en los procesadores de propósito general, creedme.&lt;br /&gt;&lt;br /&gt;Es cierto que muchos balanceadores y otros &lt;em&gt;appliance&lt;/em&gt; de red nos solucionan parte de esta problática, pero en aquellos casos en los que esto no es una opción (o en los que precisamente lo que estamos construyendo es un appliance o proxy inverso) lo que debemos es adquirir los elementos hardware aceleradores adecuados. Hoy en día las opciones son mucho más económicas y mucho más potentes que lo que mucha gente se piensa.&lt;br /&gt;&lt;br /&gt;Algunas opciones que hay en el mercado y que yo he tenido la oportunidad de probar (y poner en producción) son: &lt;ul&gt;&lt;li&gt;&lt;a href="http://www.ncipher.com/products/ssl_acceleration/22/nfast/"&gt;nFast SSL Offload (de nCipher)&lt;/a&gt;: Tarjeta de red PCI (10/100/1000) que realiza las funciones criptográficas tanto asimétricas como simétricas (esta segunda parte es relativamente novedoso) necesarias para dar servicio SSL. Lo interesante de esta tarjeta es que actúa como un proxy inverso interno. Es decir, el interfaz de red atiende mediante canal SSL pero nuestro software servidores lo configuramos para que escuche "en plano", por lo que su integración es limpia e inmediata, y compatible con cualquier software. &lt;ul&gt;&lt;li&gt;Rendimiento nominal: 10.000 transacciones SSL/TSL por segundo&lt;/li&gt;&lt;li&gt;Throughput: 300 MBit/sec Full Duplex&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.aha.com/show_prod.php?id=36"&gt;AHA363 (de Comtech AHA)&lt;/a&gt;: Tarjeta PCIe aceleradora GZIP, la más rápida del mercado. Trae una API y un módulo para Apache (aunque pueden desarrollarse otros. &lt;ul&gt;&lt;li&gt;Throughput: 5 GBit/sec&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.ncipher.com/products/hardware_security_modules/8/nshield/"&gt;nShield 500 F2 (de nCipher)&lt;/a&gt;: HSM completo que implementa todos los algoritmos de criptografía simétrica y asimétrica (incluso curvas elípticas). No se trata sólo de acelerador sino que su uso principal es la securización de claves privadas. Dentro de toda la gama de velocidades y niveles de securización, esta es más que suficiente para la mayoría de los propósitos, pero hay otras muchas opciones. &lt;ul&gt;&lt;li&gt;Rendimiento nominal: 500 firmas RSA de 1024 bits por segundo.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;¿Os imagináis un sistema de servidores frontales x64 con dos procesadores XEON Quadcore y que además incorpore estas tarjetas? Imbatible. Y sorprendentemente económico, en órdenes de magnitud los elementos que he enumerado anteriormente rondan unos PVP de 3000€, 1000€ y 5000€ respectivamente. Es decir, obviando el HSM estaríamos aproximadamente duplicando el coste de un servidor promedio de las características mencionadas. Por unos 8000-9000 € tendríamos este sistema que aceptaría una concurrencia salvaje.&lt;br /&gt;&lt;br /&gt;Obviamente tiene también sus inconvenientes, y es que cada elemento hard adicional incrementa las posibilidades de fallo, por lo que hay que considerar &lt;em&gt;spare units&lt;/em&gt; y todo lo que conlleva.&lt;br /&gt;&lt;br /&gt;Por cierto, respecto a la aceleradora GZIP no sólo estoy hablando de usarlo en la capa de servidor web / frontal, sino que fácilmente podríamos adaptar las bibliotecas Java o C de compresión para que en nuestra aplicación también utilizáramos el hardware de aceleración, e incluso hacer un JDK adaptado...&lt;br /&gt;&lt;br /&gt;En algunos casos, en realidad, no hace falta irse tan lejos. ¿Sabíais que muchas de las capacidades de nuestros procesadores modernos están infrautilizadas? Para algunos propósitos no hay mejor acelerador hardware que el procesador que ya tenemos. Tanto AMD como Intel tienen bibliotecas de alto rendimiento para operaciones de copia de arrays, matemáticas, otras útiles para compresión, cifrado, procesamiento multimedia, etc).&lt;br /&gt;&lt;br /&gt;Estoy hablando de &lt;a href="http://en.wikipedia.org/wiki/Integrated_Performance_Primitives"&gt;Intel Integrated Performance Primitives (IPP)&lt;/a&gt; y de &lt;a href="http://en.wikipedia.org/wiki/AMD_Performance_Library"&gt;AMD Performance Library (APL)&lt;/a&gt;. Un colega mío utiliza IPP para tratamiento de señales y asegura que es una auténtica maravilla, de hecho lo definió como &lt;em&gt;"los ingenieros de Intel van 20 años por delante nuestro"&lt;/em&gt;.&lt;br /&gt;&lt;br /&gt;Una de las cosas con las que algunas veces he "soñado despierto" es con que las JVM/JDK puedan estar adaptados a estos aceleradores y también utilizar esas bibliotecas de Intel y AMD. Incluso llegué a mantener una conversación con Henrik Ståhl (Product Manager de JRockit en el momento de la conversación) preguntándole/proponiéndole sobre algunas de esas especializaciones. No lo veía claro y además los costes de mantenimiento sería brutal.&lt;br /&gt;&lt;br /&gt;Por cierto que no soy el único que lo ha pensado, como puede verse en este hilo: &lt;a href="http://forums.java.net/jive/thread.jspa?messageID=224530"&gt;http://forums.java.net/jive/thread.jspa?messageID=224530&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Pero volviendo al mundo real y asumible, os aseguro que el uso de aceleración SSL es una prioridad y la aceleración GZIP una auténtica necesidad si tenemos una concurrencia tremenda (¿cómo lo hará Google Inc.? ¿con aceleradores hard con los procesadores genéricos de las nubes de servidores?)&lt;br /&gt;&lt;br /&gt;P.D.1: No he nombrado aceleradoras de gráficos, o el uso de las GPUs porque es un mundo que desconozco y que no he necesitado...&lt;br /&gt;&lt;br /&gt;P.D.2: Sólo he nombrado esas marcas y modelos porque son los que yo conozco / he tenido experiencia satisfactoria. Hay otros fabricantes como &lt;a href="http://www.safenet-inc.com/"&gt;http://www.safenet-inc.com/&lt;/a&gt; o &lt;a href="http://www.indranetworks.com/"&gt;http://www.indranetworks.com/&lt;/a&gt; con soluciones probablemente igual de válidas que las yo nombro arriba...&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Actualización 19/9/2008: En otra conversación reciente con Henrik Ståhl, me sorprendió diciéndome que el uso de código / bibliotecas específicas para cierto hardware no es algo que hayan descartado para JRockit, aunque sea complicado. Digo que me sorprende porque en la primera conversación fue bastante tajante sobre los problemas que supondría y dudaba de los beneficios, sin embargo ahora ha dejado la puerta abierta. A mi ego le gusta pensar que he podido servir de empujoncito/inspiración... &lt;/em&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-3099662114872299499?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/3099662114872299499/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=3099662114872299499' title='4 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/3099662114872299499'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/3099662114872299499'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/09/aceleradores-hardware.html' title='Aceleradores hardware'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SK6kNagMm1I/AAAAAAAAAEw/vTxtwnTt2DA/s72-c/aceleradoras.png' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-2028602000174049595</id><published>2008-09-10T21:48:00.004+02:00</published><updated>2008-11-21T10:26:03.251+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='HTTP/S'/><category scheme='http://www.blogger.com/atom/ns#' term='Glassfish/Tomcat'/><title type='text'>Glassfish V2: Performance Tuning, Tips &amp; Tricks</title><content type='html'>&lt;img style="FLOAT: right; MARGIN: 0px 0px 10px 10px" alt="" src="https://glassfish-theme.dev.java.net/logo.gif" border="0" /&gt;&lt;em&gt;[Nota octubre'08: Ver información complementaria en el post &lt;a href="http://serverperformance.blogspot.com/2008/10/tuning-de-motor-de-jsp-en-glassfish.html"&gt;Tuning de motor de JSP en Glassfish: Configuración para entorno de producción&lt;/a&gt; ]&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;En la documentación oficial de Glassfish están bastante bien documentadas las opciones de rendimiento y optimización a varios niveles (a nivel de aplicación, de servidor de aplicaciones, de JVM y de parametrización de Sistemas Operativos): &lt;ul&gt;&lt;li&gt;&lt;a href="http://wiki.glassfish.java.net/Wiki.jsp?page=PerformanceTuningGuide"&gt;Glasfish Performance Tuning guide - Index&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://docs.sun.com/app/docs/doc/819-3681"&gt;Glassfish V2 documentation [HTML]&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://dlc.sun.com/pdf/819-3681/819-3681.pdf"&gt;Glassfish V2 documentation [PDF]&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;Este blog contiene información general muy interesante sobre rendimiento de Glassfish: &lt;ul&gt;&lt;li&gt;&lt;a href="http://weblogs.java.net/blog/sdo/"&gt;Scott Oak's Blog&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;Y en esta presentación hay una relación clara y concisa de puntos de optimización en Glassfish:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://wiki.glassfish.java.net/attach/GlassFishDay2008Hyderabad/GlassFishDay2008PerfPreso.pdf"&gt;http://wiki.glassfish.java.net/attach/GlassFishDay2008Hyderabad/GlassFishDay2008PerfPreso.pdf&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;Elementos que contiene esa presentación, con mis anotaciones personales entre corchetes:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Tuning&lt;/strong&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Tuning básico a nivel de JVM &lt;em&gt;[nada nuevo]&lt;/em&gt;&lt;/li&gt;&lt;li&gt;Tuning del Web Container &lt;em&gt;[ojo que por defecto hay pocos threads y conexiones keep-alive]&lt;/em&gt;&lt;/li&gt;&lt;li&gt;Tuning del EJB Container &lt;em&gt;[idem con los tamaños de los pooles]&lt;/em&gt;&lt;/li&gt;&lt;li&gt;Tuning de la configuración en alta disponibilidad &lt;em&gt;[nada nuevo]&lt;/em&gt;&lt;/li&gt;&lt;li&gt;Tuning de Web Services y parseo de XML en general &lt;em&gt;[muy interesante el uso de Woodstox, aunque aún no por defecto, creo que la integración todavía es experimental]&lt;/em&gt;&lt;/li&gt;&lt;li&gt;Recomendaciones generales &lt;em&gt;[incluyendo la precompilación de JSPs, y deshabilitar todos aquellos elementos que no vayan a usarse]&lt;/em&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;Best practices&lt;/strong&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;... (mejor leer la PPT)&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;Es cierto que hay que tener mucho cuidado con tirar de PPTs en lugar de estudiar durante semanas, pero se agradecen este tipo de resúmenes ejecutivos, la verdad!&lt;br /&gt;&lt;br /&gt;&lt;em&gt;[Nota octubre'08: Ver información complementaria en el post &lt;a href="http://serverperformance.blogspot.com/2008/10/tuning-de-motor-de-jsp-en-glassfish.html"&gt;Tuning de motor de JSP en Glassfish: Configuración para entorno de producción&lt;/a&gt; ]&lt;/em&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-2028602000174049595?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/2028602000174049595/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=2028602000174049595' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/2028602000174049595'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/2028602000174049595'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/09/glassfish-v2-performance-tuning-tips.html' title='Glassfish V2: Performance Tuning, Tips &amp; Tricks'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-6799749870201178804</id><published>2008-09-06T16:24:00.004+02:00</published><updated>2008-11-21T10:31:13.476+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Strings/Buffers/Ficheros'/><category scheme='http://www.blogger.com/atom/ns#' term='JDK/JVM'/><category scheme='http://www.blogger.com/atom/ns#' term='Escape analysis'/><category scheme='http://www.blogger.com/atom/ns#' term='Sincronización'/><title type='text'>Copy-on-write optimization for StringBuilder and StringBuffer (II)</title><content type='html'>Continuación sobre &lt;a href="http://serverperformance.blogspot.com/2008/09/copy-on-write-optimization-for.html"&gt;Copy-on-write optimization for StringBuilder and StringBuffer&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Bien, parece que sí hay un bug en la Bug Database (no fui capaz de encontrarlo), y sobre el que se hizo un montón de investigación y pruebas, sobre JDK 1.5. Para más información, consultar &lt;a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6219959"&gt;http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6219959&lt;/a&gt;. Como se ve el bug se cerró como "Not fixed"a principios de 2006.&lt;br /&gt;&lt;br /&gt;Las explicaciones para el cambio de estrategia de copy-on-write a always-write son, resumidamente:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Cuando se derivaban Strings desde StringBuffers en JDK 1.4, había un crecimiento importante en el consumo de memoria en los Strings. Si tengo un StringBuilder con tamaño de buffer N y el String final sólo ocupa N/2 posiciones, la estrategia de compartir el buffer hace que el String ocupe el doble de memoria de lo que debería, mientras que la nueva estrategia lo ajusta.&lt;/li&gt;&lt;li&gt;Aparte de esto, está el molesto tema de la inmutabilidad de los Strings. Si se hiciera mal uso de un StringBuilder (ojo, el problema no se daría en StringBuffer), podría darse el caso durante un pequeño lapso de tiempo de que de que un thread esté leyendo un String mientras que otro esté cambiando su contenido porque aún no se haya enterado de la compartición. Casi imposible en la práctica pero teóricamente posible, así que...&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Queda el consuelo, leyendo la descripción del bug, de que los ingenieros de Sun pasaron muchas horas con el tema, que cualquier posibilidad que a mi se me iba ocurriendo ya la han considerado (gracioso, en el bug va diciendo "uno podría argumentar que...", "también podría pensarse en...", justo lo que yo había deliverado :-) ).&lt;/p&gt;&lt;p&gt;Y queda el consuelo de que tanto en el foro como el en bug se llega a la conclusión de que un escape analisis sería una solución válida para que Hotspot decidiera hacer la optimización cuando una regiiónd e código sólo es alcanzada por un thread a la vez. Otra cosa es si el esfuerzo merece la pena, claro...&lt;/p&gt;&lt;p&gt;Tengo una idea cojonuda en esta línea. Voy a darle unas vueltas y a proponerla. Tanto en este blog como en el foro de rendimiento.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-6799749870201178804?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/6799749870201178804/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=6799749870201178804' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/6799749870201178804'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/6799749870201178804'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/09/copy-on-write-optimization-for_06.html' title='Copy-on-write optimization for StringBuilder and StringBuffer (II)'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-491778034473330917</id><published>2008-09-05T00:41:00.007+02:00</published><updated>2008-11-21T10:31:16.688+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Strings/Buffers/Ficheros'/><category scheme='http://www.blogger.com/atom/ns#' term='JDK/JVM'/><category scheme='http://www.blogger.com/atom/ns#' term='Sincronización'/><title type='text'>Copy-on-write optimization for StringBuilder and StringBuffer</title><content type='html'>Hoy he publicado mi primer post en el foro "General performance Discussion" @java.net:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://forums.java.net/jive/thread.jspa?messageID=297309"&gt;http://forums.java.net/jive/thread.jspa?messageID=297309&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://forums.java.net/"&gt;&lt;img style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="Forums @ java.net" src="http://www.java.net/images/header_jnet_new.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Pego directamente (en inglés, me ha costado lo mío, je je):&lt;br /&gt;&lt;blockquote&gt;&lt;span style="FONT-STYLE: italic"&gt;Hello everybody.&lt;br /&gt;&lt;br /&gt;The old 1.4 version of StringBuffer had a very nice implementation of a "copy-on-write" (COW), [as have the C++ String and the .NET StringBuilder, I think]. In few words: when the toString() method is called, it doesn't copy the char array to the String, but shares it with the String and marks as "shared" inside; and if there are future call to insert or remove or others in the "immutable" section of the char array, then creates a copy of the array and goes on (so the String keep immutable and the StringB can mute.&lt;br /&gt;&lt;br /&gt;For some reason, this changed in JDK 1.5, becoming in a "always copy" strategy. Why? Haven't find it. I have only found the forum entry dated in 2005: &lt;/span&gt;&lt;a href="http://forums.java.net/jive/thread.jspa?messageID=29032"&gt;&lt;span class="Apple-style-span" style="FONT-STYLE: italic"&gt;http://forums.java.net/jive/thread.jspa?messageID=29032&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="FONT-STYLE: italic"&gt;.&lt;br /&gt;&lt;br /&gt;I don't understand what kind of concurrency problem that the COW approximation has. Can someone put the light on me?&lt;br /&gt;&lt;br /&gt;For testing, I have hacked AbstractBuilder, StringBuilder and StringBuffer with the COW hack. And in a microbenchmark there is a significant boost in both cases, also NetBeans, Glassfish, my J2EE apps and so on worked great with this patch. Sorry but no deep multithreading testing...&lt;br /&gt;&lt;br /&gt;Why not reintroducing it in JDK 7? No API changes, cheap change, and a good boost.&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;Salvo que tenga unos problemas rarísimos que mi corta mente no llega a alcanzar, no veo por qué no... al fin y al cabo StringBuilder es thread-unsafe de por si, y StringBuffer... bueno, si funcionaba el COW en versiones anteriores del JDK no veo la diferencia (a no ser que no fuera realmente thread-safe, claro :-)&lt;br /&gt;&lt;br /&gt;Por espacio, no pego el código de AbstractBuilder, StringBuilder y StringBuffer que he tocado, es algo distinto al 1.4 pero el concepto es el mismo...&lt;br /&gt;&lt;br /&gt;Hilos (para el que tenga interés en los detalles concretos, de momento podéis revisar ambos hilos): &lt;ul&gt;&lt;li&gt;&lt;a href="http://forums.java.net/jive/thread.jspa?messageID=297309"&gt;http://forums.java.net/jive/thread.jspa?messageID=297309&lt;/a&gt;&lt;/li&gt;&lt;li&gt;También he puesto un comentario en el blog de Jeremy Manson, en la entrada &lt;a href="http://jeremymanson.blogspot.com/2008/08/dont-use-stringbuffer.html"&gt;Don't Use StringBuffer!&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Actualización - 05/09/2008:&lt;/span&gt;&lt;br /&gt;Parece más un problema de consumo de memoria que de sincronización. Entiendo perfectamente el tema (puede verse en la &lt;a href="http://bugs.sun.com/bugdatabase/"&gt;Bug Database&lt;/a&gt;, bugs 4259569, 4724129, 4524848, 4910256), pero es una auténtica pena por el acelerón que supondría. Así que en el foro he propuesto combinar esta opción con &lt;code&gt;-XX:+AggressiveOpts&lt;/code&gt;. Seguremos informando...&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-491778034473330917?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/491778034473330917/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=491778034473330917' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/491778034473330917'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/491778034473330917'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/09/copy-on-write-optimization-for.html' title='Copy-on-write optimization for StringBuilder and StringBuffer'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-6390598012105357630</id><published>2008-09-01T09:55:00.007+02:00</published><updated>2008-11-21T10:29:33.921+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JDK/JVM'/><category scheme='http://www.blogger.com/atom/ns#' term='Benchmarks'/><category scheme='http://www.blogger.com/atom/ns#' term='Escape analysis'/><category scheme='http://www.blogger.com/atom/ns#' term='Sincronización'/><title type='text'>¿Funcionan las optimizaciones sobre el modelo de threading?</title><content type='html'>&lt;a href="http://www.infoq.com/articles/java-threading-optimizations-p1"&gt;http://www.infoq.com/articles/java-threading-optimizations-p1&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Interesantísimo &lt;a href="http://www.infoq.com/articles/java-threading-optimizations-p1"&gt;artículo&lt;/a&gt;, que explica varias de las opciones de arranque de la JVM que yo recomendaba en el post &lt;a href="http://serverperformance.blogspot.com/2008/08/jvm-tunning-parmetros-de-lanzamiento-de.html"&gt;JVM tuning: Parámetros de lanzamiento de JVM: Sun Hotspot&lt;/a&gt;, complementando así la información que publiqué en el post &lt;a href="http://serverperformance.blogspot.com/2008/08/allocation-deallocation-and-escape.html"&gt;Allocation, deallocation and escape analysis for Java&lt;/a&gt; . Trata los siguientes conceptos:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Escape analysis - lock elision explained&lt;/li&gt;&lt;li&gt;Biased locking explained&lt;/li&gt;&lt;li&gt;Lock coarsening explained&lt;/li&gt;&lt;li&gt;Adaptive spinning explained&lt;/li&gt;&lt;/ul&gt;Adicionalmente presenta los resultados de un benchmarking hecho por él mismo probando combinaciones de varias de estas opciones y comparando el rendimiento de StringBuffer vs StringBuilder en ellas. Si la magia existiera, los tiempos del StringBuffer deberían tender a los del StringBuilder al aplicar todas las optimizaciones. Sus resultados:&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://www.infoq.com/resource/articles/java-threading-optimizations-p1/en/resources/image.png"&gt;&lt;img style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 320px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://www.infoq.com/resource/articles/java-threading-optimizations-p1/en/resources/image.png" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Mis resultados en Linux x64 con 2xXEONx4Cores:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Son similares a estos en cuanto a los &lt;a href="http://serverperformance.blogspot.com/2008/08/jvm-tunning-parmetros-de-lanzamiento-de.html"&gt;parámetros que más contribuyen&lt;/a&gt; al rendimiento y en cuanto a que "la magia no existe: usa versiones no sincronizadas de las clases!". Nota: las pruebas de rendimiento sobre varios núcleos y/o varios procesadores son muy distintas que en máquinas con un sólo núcleo, donde no hay contención entre threads "reales".&lt;/li&gt;&lt;li&gt;Curiosamente, en mis pruebas con distintas versiones del JDK (1.5, 1.6.0_07, 1.6.0_06-6p, y JRockit) he visto cómo el rendimiento en la "Performance Release 6" se ha incrementado drásticamente en el uso de StringBuilders frente a la edición "normal" de Java 6 (que por cieto es más lenta que JDK 1.5), pero no tanto de StringBuffers. Y también que los resultados de JRockit en ambos casos eran los mismos, es decir que JRockit sí que optimiza correctamente cuando no hay contención posible y Hotspot no del todo...&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-6390598012105357630?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/6390598012105357630/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=6390598012105357630' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/6390598012105357630'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/6390598012105357630'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/09/funcionan-las-optimizaciones-sobre-el.html' title='¿Funcionan las optimizaciones sobre el modelo de threading?'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-1583608006284361410</id><published>2008-08-29T00:31:00.004+02:00</published><updated>2008-11-21T10:26:10.721+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='HTTP/S'/><category scheme='http://www.blogger.com/atom/ns#' term='Sincronización'/><category scheme='http://www.blogger.com/atom/ns#' term='General'/><category scheme='http://www.blogger.com/atom/ns#' term='Glassfish/Tomcat'/><category scheme='http://www.blogger.com/atom/ns#' term='NIO'/><title type='text'>Es la guerra: IO vs "non blocking NIO"</title><content type='html'>&lt;img style="MARGIN: 10px" alt="" src="http://weblogs.java.net/blog/sdo/archive/images/jbench.png" border="0" /&gt;&lt;br /&gt;En esta &lt;a href="http://serverperformance.blogspot.com/2008/06/mitos-sobre-rendimiento-y-escalabilidad.html"&gt;entrada anterior&lt;/a&gt; hice una pequeña y somera referencia hacia que los procesadores multicore y el uso de NPTL y otras librerías de threads optimizadas, pueden haber cambiado las reglas del juego. Y no estar tan claro que la E/S no bloqueante merezca la pena frente a una IO bloqueante "de toda la vida".&lt;br /&gt;&lt;br /&gt;Parece que a lo largo de 2008 se ha armado un pequeño revuelo / revolución a este respecto. Como muestra estos dos botones: &lt;ul&gt;&lt;li&gt;A favor de IO síncrona: &lt;a href="http://mailinator.blogspot.com/2008/02/kill-myth-please-nio-is-not-faster-than.html"&gt;http://mailinator.blogspot.com/2008/02/kill-myth-please-nio-is-not-faster-than.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Y la respuesta: &lt;a href="http://weblogs.java.net/blog/sdo/archive/2008/04/more_on_the_sim.html"&gt;http://weblogs.java.net/blog/sdo/archive/2008/04/more_on_the_sim.html&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;En definitiva, mi conclusión personal es la siguiente para máquinas de 8-32 cores: &lt;ol&gt;&lt;li&gt;Servidores con poca concurrencia esperada: IO síncrona&lt;/li&gt;&lt;li&gt;Servidores con concurrencia media esperada: IO síncrona&lt;/li&gt;&lt;li&gt;Servidores con concurrencia alta esperada: depende, habría que probarlo&lt;/li&gt;&lt;li&gt;Servidores con concurrencia brutal esperada: NIO asíncrona&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;En los escenarios 1 y 2, seguramente el problema de rendimiento y escalabilidad lo tengamos en otro sitio así que este no es un tema tan crítico en esos casos.&lt;/p&gt;En cualquier caso, depende del uso y de lo que entendamos por poca o mucha concurrencia. El otro día un colega al que respeto un montón me comentaba que lo estamos viendo con un punto de vista exclusivamente de "contenidos de hipertexto"; en un entorno de servir contenidos multimedia el tiempo de cambio de contexto entre threads es inasumible de ninguna de las maneras.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-1583608006284361410?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/1583608006284361410/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=1583608006284361410' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/1583608006284361410'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/1583608006284361410'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/08/es-la-guerra-io-vs-non-blocking-nio.html' title='Es la guerra: IO vs &quot;non blocking NIO&quot;'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-5656111129175774855</id><published>2008-08-24T20:23:00.006+02:00</published><updated>2008-11-21T10:28:12.854+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JDK/JVM'/><title type='text'>Java SE 6u6-p Performance Release - YA DISPONIBLE EN OTRAS PLATAFORMAS</title><content type='html'>&lt;p style="FONT-STYLE: italic"&gt;[Notas de octubre'08 y noviembre'08 ==&gt;&lt;/p&gt;&lt;p style="FONT-STYLE: italic"&gt;Querido googler: si llegas a esta página -como muchos- buscando información de las performance releases del JRE 6, quizás te interesen los artículos posteriores &lt;a href="http://serverperformance.blogspot.com/2008/09/6u6-p-pues-en-linux-x64-peta.html"&gt;6u6-p: Pues en Linux x64 peta!!!!!!!&lt;/a&gt; y &lt;a href="http://serverperformance.blogspot.com/2008/11/identificacin-de-bugs-en-la-versin-6u6p.html"&gt;Identificación de bugs en la versión 6u6p y workaround&lt;/a&gt; ]&lt;/p&gt;&lt;br /&gt;En la entrada &lt;a href="http://serverperformance.blogspot.com/2008/07/java-se-6u6p-performance-release.html"&gt;Java SE 6u6p Performance Release&lt;/a&gt; remarqué que en julio estaba ya disponible la versión 6u6-p Performance Release, pero sólo lo estaba para Solaris 64 bits.&lt;br /&gt;&lt;br /&gt;Pues bien, por fin ya está disponible para un número más que interesante de otras plataformas, y la sopresa es que no sólo de 64 bits sino también algunas de 32 bits:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_4ZEuwiCuF6A/SK1ferxluQI/AAAAAAAAAEc/ntzWFRxZBXI/s1600-h/6u6-p.png"&gt;&lt;img id="BLOGGER_PHOTO_ID_5236946922453186818" style="DISPLAY: block; MARGIN: 0px auto 10px; TEXT-ALIGN: center" alt="" src="http://3.bp.blogspot.com/_4ZEuwiCuF6A/SK1ferxluQI/AAAAAAAAAEc/ntzWFRxZBXI/s400/6u6-p.png" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Ala, a rellenar el cuestionario en &lt;a href="http://java.sun.com/javase/performance/survey.html"&gt;http://java.sun.com/javase/performance/survey.html&lt;/a&gt; y descargar, a ver qué tal...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-5656111129175774855?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/5656111129175774855/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=5656111129175774855' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/5656111129175774855'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/5656111129175774855'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/08/java-se-6u6-p-performance-release-ya.html' title='Java SE 6u6-p Performance Release - YA DISPONIBLE EN OTRAS PLATAFORMAS'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_4ZEuwiCuF6A/SK1ferxluQI/AAAAAAAAAEc/ntzWFRxZBXI/s72-c/6u6-p.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-922828321581762614</id><published>2008-08-20T22:57:00.009+02:00</published><updated>2009-02-25T13:27:05.178+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GC'/><category scheme='http://www.blogger.com/atom/ns#' term='JDK/JVM'/><category scheme='http://www.blogger.com/atom/ns#' term='Escape analysis'/><category scheme='http://www.blogger.com/atom/ns#' term='Sincronización'/><category scheme='http://www.blogger.com/atom/ns#' term='Memoria'/><title type='text'>Allocation, deallocation and escape analysis for Java</title><content type='html'>&lt;a href="https://duke.dev.java.net/images/thinking/Thinking.jpg"&gt;&lt;img style="MARGIN: 0px 0px 10px 10px; WIDTH: 100px; FLOAT: right; CURSOR: hand" border="0" alt="" src="https://duke.dev.java.net/images/thinking/Thinking.jpg" /&gt;&lt;/a&gt; &lt;div&gt;Enlazo con este interesante artículo en IBM Developer Works: &lt;ul&gt;&lt;li&gt;&lt;a href="http://www-128.ibm.com/developerworks/java/library/j-jtp09275.html"&gt;http://www-128.ibm.com/developerworks/java/library/j-jtp09275.html&lt;/a&gt; (que es una addenda hecha en 2005 a este otro artículo de 2003 &lt;a href="http://www.ibm.com/developerworks/java/library/j-jtp04223.html"&gt;http://www.ibm.com/developerworks/java/library/j-jtp04223.html&lt;/a&gt;).&lt;/li&gt;&lt;li&gt;Y para información general acerca de qué es el Escape Analysis: &lt;a href="http://en.wikipedia.org/wiki/Escape_analysis"&gt;http://en.wikipedia.org/wiki/Escape_analysis&lt;/a&gt;. Palabra de dios :-)&lt;/li&gt;&lt;/ul&gt;Básicamente el anterior post trata dos temas muy interesantes desde el punto de vista &lt;strong&gt;teórico&lt;/strong&gt;:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;El mínimo coste de la creación de objetos y reserva de memoria en Java frente a C/C++. Esto es gracias a la arquitectura interna con intervención del GC.&lt;/li&gt;&lt;li&gt;La inclusión del Escape Analysis en Java 6 y cómo eso beneficia al alojamiento de objetos en el stack frente al heap, lo cual puede ser una signfiicativa mejora de rendimiento...&lt;/li&gt;&lt;/ul&gt;Pues bien, el segundo de ellos parece que todavía no es cierto en Java 6 (el artículo es de 2005). Básicamente, hasta donde yo sé, sí que está implementado el análisis de escape (con la opción &lt;code&gt;-XX:+DoEscapeAnalysis&lt;/code&gt;) pero sólo se usa para eliminar bloqueos, no para el alojamiento en stack. Quizás en Java 7 la optimización sea completa...&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;En este hilo puede verse la misma conclusión: &lt;a href="http://forums.java.net/jive/thread.jspa?threadID=22617&amp;amp;tstart=120"&gt;http://forums.java.net/jive/thread.jspa?threadID=22617&amp;amp;tstart=120&lt;/a&gt;. Sin embargo en este otro post de 2007 se asegura que el Escape Analysis se eliminó de Mustang, por lo que me surge la duda si en actualizaciones posteriores sí se hizo o si simplemente es que hay desinformación por ahí... ver: &lt;a href="http://blog.nirav.name/2007/02/escape-analysis-in-mustang-ii.html"&gt;http://blog.nirav.name/2007/02/escape-analysis-in-mustang-ii.html&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Y en cualquier caso con los microbenchmarks que yo he hecho (Linux, kernel 2.6, 8 cores) no parece que se gane mucho en cuanto a eliminación de locks, sí que parece suponer una mínima mejora pero nada comparable con el biased locking. Con todo el miedo que tengo a los microbenchmarks, en cualquier caso lo cierto es que la opción &lt;code&gt;UseBiasedLocking&lt;/code&gt; está activada por defecto en Java 6, mientras que &lt;code&gt;DoEscapeAnalysis&lt;/code&gt; hay que activarla.&lt;br /&gt;&lt;br /&gt;El sentido común me dice que la decisión de poner opciones por defecto (o no ponerlas) por algo será (si partimos de la premisa de que los ingenieros de Sun no son imbéciles profundos ;-) y por lo tanto seguramente es un análisis experimental e imperfecto, así que tendremos que esperar a Java 7 para que ambas líneas de aprovechamiento del "análisis de escape" funcionen adecuadamente.&lt;br /&gt;&lt;br /&gt;P.D: en otro post comentaré acerca del peligro de los microbenchmarks y cómo deben hacerse para no obtener resultados equivocados (en teoría, aunque tampoco me fío del todo).&lt;/p&gt;&lt;p&gt;&lt;em&gt;[Actualización: puede verse información más detallada sobre esta y otras opciones de optimizaciones sobre el modelo de Threading en el post &lt;/em&gt;&lt;a href="http://serverperformance.blogspot.com/2008/09/funcionan-las-optimizaciones-sobre-el.html"&gt;&lt;em&gt;¿Funcionan las optimizaciones sobre el modelo de threading?&lt;/em&gt;&lt;/a&gt;&lt;em&gt;]&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;[Actualización 06-09-2008: Definición de Escape analysis en la Wikipedia: &lt;a href="http://en.wikipedia.org/wiki/Escape_analysis"&gt;http://en.wikipedia.org/wiki/Escape_analysis&lt;/a&gt;]&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;[Actualización 04-11-2008: Conceptos generales de rendimiento en Java, incluyendo estos nombrados: &lt;a href="http://en.wikipedia.org/wiki/Java_performance"&gt;http://en.wikipedia.org/wiki/Java_performance&lt;/a&gt;]&lt;/em&gt;&lt;/p&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-922828321581762614?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/922828321581762614/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=922828321581762614' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/922828321581762614'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/922828321581762614'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/08/allocation-deallocation-and-escape.html' title='Allocation, deallocation and escape analysis for Java'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-7122429832825285823</id><published>2008-08-08T08:08:00.013+02:00</published><updated>2008-12-10T12:55:14.477+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GC'/><category scheme='http://www.blogger.com/atom/ns#' term='JDK/JVM'/><category scheme='http://www.blogger.com/atom/ns#' term='Out-of-box'/><category scheme='http://www.blogger.com/atom/ns#' term='Memoria'/><title type='text'>JVM tuning: Parámetros de lanzamiento de JVM: Sun Hotspot</title><content type='html'>&lt;a href="http://4.bp.blogspot.com/_4ZEuwiCuF6A/SI9LsII24sI/AAAAAAAAAEM/Az9mkoTFfpk/s1600-h/TuningRomania_0.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5228480913871397570" style="FLOAT: right; MARGIN: 0px 0px 10px 10px; CURSOR: hand" alt="" src="http://4.bp.blogspot.com/_4ZEuwiCuF6A/SI9LsII24sI/AAAAAAAAAEM/Az9mkoTFfpk/s320/TuningRomania_0.jpg" border="0" /&gt;&lt;/a&gt;&lt;em&gt;[Artículo actualizado el 3/11/2008 con información adicional sobre -XX:+DoEscapeAnalysis y -XX:+AggressiveOpts].&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;Parámetros de lanzamiento. JVM options. VM options. JDK option. Tuning parameter. Tunning.&lt;br /&gt;&lt;br /&gt;O como queráis llamarlo. Por cierto que no se escribe Tunning, sino Tuning. a mi se me escapa mucho.&lt;br /&gt;&lt;br /&gt;Sí, es tuning, pero no del de la foto :-)&lt;br /&gt;&lt;br /&gt;La cuestión es de sobra comentada en este blog: cada vez el rendimiento sin tunear, o "Out-of-box performance" se aproxima más al mejor de los casos. Es decir en condiciones extremas puede haber una diferencia del 8% (que no es poco) pero puede ser un margen más que suficiente para no meterse en líos. Porque por toquitear podemos cagarla. Ahora o en un futuro. Pueden revisarse las reflexiones en la serie relacionada con la etiqueta &lt;a href="http://serverperformance.blogspot.com/search/label/Out-of-box"&gt;Out-of-box&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;A lo que vamos. Pero vale la pena intentarlo. Es más, casi diría que tenemos la obligación de intentarlo, cada aplicación es un mundo, los comportamientos de nuestros usuarios son otro mundo y las configuraciones y otros elementos para qué contarlo.&lt;br /&gt;&lt;br /&gt;De todas formas, insisto en que no debe tunear por tunear, ni dejarse llevar por lo que supuesto expertos y teóricos aseguran en sus blogs (¿como este?). Las reglas de oro, en mi experiencia, son las siguientes:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;No te fíes de la teoría. O de los expertillos de salón. O de "tu intuición e inteligencia". Ni mucho menos de la de tu jefe. &lt;strong&gt;Prueba tú mismo la inclusión de opciones nuevas.&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;No hagas Microbenchmarks&lt;/strong&gt;. Mejor no hacerlos, puede llevar a conclusiones erróneas gracias a las optimizaciones (o no optimizaciones del Hotspot); aunque te creas más listo que nadie y pienses que lo estás simulando bien, lo más probable es que no sea así. Simula siempre con tu aplicación, no con un programita de esos que haces siempre para tomar tiempos.&lt;/li&gt;&lt;li&gt;Paso 1: No tuning. &lt;strong&gt;Out-of-box&lt;/strong&gt;. Déjalo como está (sin configurar o preconfigurado para tu servidor de aplicaciones), tocando únicamente los targets de memoria en cuanto a heap y revisando que aparezca el &lt;code&gt;-server&lt;/code&gt; (por ejemplo en Glassfish V2, el comilador es &lt;code&gt;-client&lt;/code&gt; por defecto). Si el rendimiento en el entorno de ejecución es adecuado, incluso en situaciones de carga, no lo toques. Si funciona no lo toques.&lt;/li&gt;&lt;li&gt;Paso 2: Comienza a hacer &lt;strong&gt;pruebas de carga sobre tu sistema&lt;/strong&gt; en pre-explotación. O en explotación. Pero pruebas de verdad, con un &lt;strong&gt;juego de pruebas coherente&lt;/strong&gt;, con sus pausas aleatorias y la carga distribuida en distintos clientes con distintos anchos de banda simulado o real. Y ejecutado durante &lt;strong&gt;más de 2 horas cada uno&lt;/strong&gt;. Lo mejor sería que las pruebas no fueran sintéticas 100% sino en base a los logs de ejecuciones pasadas, pausas, etc. &lt;ol&gt;&lt;li&gt;Parte de la configuración base. Toma los tiempos de referencia.&lt;/li&gt;&lt;li&gt;Sigue los pasos del apartado 4.2 del documento &lt;a href="http://java.sun.com/performance/reference/whitepapers/tuning.html#section4.2"&gt;http://java.sun.com/performance/reference/whitepapers/tuning.html#section4.2&lt;/a&gt;. Empieza por el ejemplo 1. Aplica los parámetros y toma tiempos&lt;/li&gt;&lt;li&gt;Repite el paso anterior con los ejemplo 2..7. Toma tiempos de todo ellos.&lt;/li&gt;&lt;li&gt;Revisar las configuraciones de resultados publicados para los benchmarks del SPEC, y prueba con alguna de ellas (abajo pego un ejemplo).&lt;/li&gt;&lt;li&gt;Por supuesto hay otras miles de opciones, muchas indocumentadas lamentablemente. Si tienes tiempo, ya sabes. ¡A probar!&lt;/li&gt;&lt;li&gt;Toma tus propias conclusiones. Recuerda que un objetivo más importante que el rendimiento es la estabilidad al cabo del tiempo.&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Menos es más&lt;/strong&gt; (esto también lo dicen los chicos de Usabilidad). Si dos alternativas dan resultados casi equivalentes, opta por la que menos opciones de lanzamiento tenga.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Cada vez &lt;/strong&gt;que cambies de versión de JDK, de versión de servidor de aplicaciones, de versión del kernel, o de hardware vuelve a hacer las comprobaciones, a no ser que en las notas de la versión dejen muy claro que sólo corrigen bugs que no te afectan. Apúntatelo en la cabecita. O en la libreta. O en la documentación. Un parámetro óptimo para una versión puede ser peor que la opción por defecto para la siguiente versión.&lt;/li&gt;&lt;/ol&gt;Dicho esto, y sabiendo que cada sistema y aplicación es un mundo, y los objetivos de negocio otro, voy a poner a continuación las opciones que a mi más mejor me funcionan.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Mi configuración HW y soft base, resumidamente es: máquinas x64, 2 procesadores XEON Quadcore (8 núcleos por máquina en total), 16 Gbytes de RAM, discos SAS en RAID 1, CentOS 5.1 kernel 2.6.18.&lt;/li&gt;&lt;li&gt;Viendo las configuraciones de resultados publicados en SPECjbb2005, una configuración que se repite con frecuencia es más o menos: &lt;ul&gt;&lt;li&gt;&lt;strong&gt;Para Hotspot&lt;/strong&gt;: &lt;code&gt;-Xms3650m -Xmx3650m -Xmn2000m -server -XX:+UseBiasedLocking -XX:+AggressiveOpts -XX:+UseParallelOldGC -Xss128k -XX:+UseLargePages -Xbatch&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Para JRockit:&lt;/strong&gt; &lt;code&gt;-Xms3650m -Xmx3650m -Xns3000m -XXaggressive -XXlazyunlocking -Xlargepages -Xgc:genpar -XXtlasize:min=4k,preferred=1024k -XXcallprofiling&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;Lo que más me ha llamado la atención es que en casi ninguna configuración se abusa del tamaño de heap, aunque la JVM sea de 64bits en los tests no pasan de 3 GBytes de heap máximo. ¿Por qué? por tiempo de recolección de basura por supuesto. Esta puede ser una configuración válida para un benchmarking, pero en mi opinión es absurdo no aprovechar todo lo que nos da la máquina (o casi todo).&lt;br /&gt;&lt;br /&gt;Los parámetros que mejores resultados me dan &lt;strong&gt;a mi en mi sistema y con mis circunstancias&lt;/strong&gt;, y con estabilidad, son los siguientes, tanto en JDK 1.5 como en Java 6 (aunque en Java 6 algunas de ellas son valores ya por defecto): "&lt;code&gt;-server -Xmx12288m -Xms12288m -XX:MaxPermSize=256m -XX:+UseParallelOldGC -XX:+UseAdaptiveSizePolicy -XX:+UseBiasedLocking -XX:+EliminateLocks -XX:+AggressiveOpts -Xverify:none -Djava.net.preferIPv4Stack=true&lt;/code&gt;"&lt;br /&gt;&lt;br /&gt;De todo ello, lo más importante es elegir una buena estrategia de recolección de basura. En uno de los enlaces abajo están perfectamente explicadas todas las estrategias actuales, en mi caso el "stop-the-world" apenas se nota frente a una diferencia importante de rendimiento con estrategias concurrentes, quizás sea porque mi gráfico de objetos sea muy simple, un número medio de objetos con gran tamaño.&lt;br /&gt;&lt;br /&gt;Un breve comentario de ellas:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;-server&lt;/code&gt;: Entre otras diferencias con el modo cliente es el número de iteraciones antes de compilar una zona de código, 10000 frente a 1500. Se puede cambiar con la opción &lt;code&gt;-XX:CompileThreshold&lt;/code&gt;, pero curiosamente mis pruebas han dado que un número ideal tiende a 7000-10000, indicando 0 o similar da resultados catastróficos... parece ser que por los inlinings y elecciones correctas, qué curioso. Nota: la opción -client puede ser la adecuada si lo que necesitas es buen tiempo de arranque o en situaciones en las que cambian mucho los JSP (cada JSP recompila a una nueva versión de la clase Servlet generada), pero algunas de las siguientes opciones no funcionarán.&lt;/li&gt;&lt;li&gt;&lt;code&gt;-Xmx&lt;/code&gt;: tamaño máximo del heap, aún no tengo claro si incluye o no la zona de PermGen. Regla de oro: curiosamente la máquina donde se ejecutan JVM &lt;strong&gt;JAMÁS&lt;/strong&gt; debe utilizar el swap a disco, la GC sería un desastre si tiene que ir moviendo páginas de un lado a otro.&lt;/li&gt;&lt;li&gt;&lt;code&gt;-Xms&lt;/code&gt;: tamaño inicial del heap, en todos los sitios se recomienda igualarlo al máximo por rollos de fragmentación. Nota: esto no significa que el proceso consuma desde el principio esa cantidad de memoria física.&lt;/li&gt;&lt;li&gt;&lt;code&gt;-XX:MaxPermSize&lt;/code&gt;: tamaño de la zona de generación permanente, donde nunca se hace GC (creo) ahí se alojan los objetos "clase" por ejemplo. Normalmente con 64 megas es más que suficiente pero si tienes muchos JSPs o muchos EJBs, mejor subirlo por si acaso (en Java CAPS por defecto es 192 megas).&lt;/li&gt;&lt;li&gt;&lt;code&gt;-XX:+UseParallelOldGC&lt;/code&gt;: estrategia de máxima paralelización en la recolección de basura, no sólo usa múltples threads (por defecto tantos como threads reales máximos soporta tu máquina) en la recolección en las zonas jóvenes, sino también paraleliza la recolección en la zona antigua del heap. La opción por defecto con -server es &lt;code&gt;UseParallelGC&lt;/code&gt;, en mi caso había una diferencia perceptible entre ambas. En muchos casos la opción adecuada debería ser &lt;code&gt;-XX:+UseConcMarkSweepGC&lt;/code&gt;, en el que virtualmente no hay pausas perceptibles, pero el rendimiento global es menor. Por cierto, si vas al límite de consumo de heap o tienes algún memory leak, esta opción puede ser un desastre porque los tiempos de "stop de world" se hacen infinitos ya que no encuentra nada que liberar...&lt;/li&gt;&lt;li&gt;&lt;code&gt;-XX:+UseAdaptiveSizePolicy&lt;/code&gt;: para no liarse con los tamaños de cada zona del heap, en mi caso lo mejor ha sido indicar este parámetro para que sea Hotspot quien vaya decidiendo y redimensionando por mi. Obviamente lo mejor es que no haya redimensiones y usar parámetros como &lt;code&gt;-Xmn&lt;/code&gt;, &lt;code&gt;-XX:NewRatio=2&lt;/code&gt; y similares, pero hay que tener mucho cuidado porque pueden empezar a saltar OutOfMemory's cuando no deberían...&lt;/li&gt;&lt;li&gt;&lt;code&gt;-XX:+AggressiveOpts&lt;/code&gt;: &lt;strike&gt;Aplica (si las hay) optimizaciones experimentales que se liberarán oficialmente en siguientes versiones del JDK.&lt;/strike&gt;Habilita aquellas opciones de rendimiento que se prevén como habilitadas por defecto en siguientes releases del Hotspot, &lt;strong&gt;es decir muchas de las que explícitamente se especifican a continuación en realidad no es necesario indicarlas si aparece esta opción&lt;/strong&gt;. Yo lo he usado siempre y nunca ha habido un comportamiento raro. En mi caso sí que aportaba un 1-2% de mejora sin afectar a la estabilidad, si no es el caso mejor no ponerlo por si acaso.&lt;/li&gt;&lt;li&gt;&lt;code&gt;-XX:+UseBiasedLocking&lt;/code&gt;: Utiliza una estrategia de bloqueo que beneficia escenarios en los que sólo un thread pasa por una región de exclusión mutua (reduce la "contención") pero penaliza algunas estrategias de bloqueo. Teniendo en cuenta que la mitad del JDK está sincronizado y que no suele unsarse un String o un ByteArray desde dos threads concurrentes, es una gran idea. En Java 6 está habilitado por defecto, en JDK 1.5 hay que habilitarlo o especificar +AggresiveOpts.&lt;/li&gt;&lt;li&gt;&lt;code&gt;-XX:+EliminateLocks&lt;/code&gt;: Otra técnica de optimización que se nota levemente, básicamente unifica regiones de exclusión mutua en un mismo thread. Una vez más el diseño de las clases del JDk hace que esta estrategia sea beneficiosa. Creo que no está habilitado por defecto en Java 6, salvo que especifiques +AggresiveOpts.&lt;/li&gt;&lt;li&gt;&lt;code&gt;-Xverify:none&lt;/code&gt;: no verifica todas las clases contenidas en el bootclasspath y resto de cargas(ncluyendo el escaneo de todos los JARs) al arrancar. Acelera la fase de lanzamiento pero más vale ir con ojo porque está deshabilitando un control que mejor activar tras un par de semanas de funcionamiento. &lt;strong&gt;Cuidado por tanto con deshabilitar a la ligera la verificación si desplegamos código no confiable o de proveedores externos en nuestros servidores de aplicaciones, ya que esto puede derivar en alguna vulnerabilidad.&lt;/strong&gt; &lt;li&gt;&lt;code&gt;-Djava.net.preferIPv4Stack=true&lt;/code&gt;: Bueno, básicamente que no utilice el stack de IPv6 para el networking. Si no usas IPv6, activa esta opción y verás...&lt;/li&gt;&lt;li&gt;[&lt;code&gt;-XX:+DoEscapeAnalysis&lt;/code&gt;: Esta es una opción que no está en JDK 1.5 y sí en Java 6 y JDK 7, en mis microbenckmarks daba peores resultados que desactivándolo curiosamente, aunque la teoría dice que debería funcionar para eliminar locks en regiones por las que sólo puede pasar un thread a la vez] &lt;em&gt;NOTA DE REVISIÓN DE 3/11/2008: esta opción se habilita al establecer +AggresiveOpts, por lo que los microbenchmarks habría que revisarlos, porque los benchmars reales dan mejor resultado con +AggresiveOpts que sin ella&lt;/em&gt;.&lt;/li&gt;&lt;li&gt;&lt;em&gt;[Otras opciones como -XX:+UseFastAccessorMethods y -XX:+StringCache no las he probado explícitamente. Al menos el primero de ellos creo que stá habilitado por defecto en todas las VM, y el segundo no lo tengo claro pero estoy casi convencido de que se ve afectado por +AggresiveOpts.]&lt;/em&gt;&lt;/li&gt;&lt;/ul&gt;Insisto, lo mejor es dejar el máximo número de opciones a su valor por defecto, aunque a todos nos gusta tunear. Y no te fies de los blogs. ¡Ni de este! Prueba, prueba y prueba&lt;br /&gt;&lt;br /&gt;Ver algunas explicaciones y enlaces de interés en:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://java.sun.com/performance/reference/whitepapers/tuning.html"&gt;http://java.sun.com/performance/reference/whitepapers/tuning.html&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href="http://java.sun.com/javase/technologies/hotspot/vmoptions.jsp"&gt;http://java.sun.com/javase/technologies/hotspot/vmoptions.jsp&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href="http://www.makeitfly.co.uk/Presentations/java_mt_performance.pdf"&gt;http://www.makeitfly.co.uk/Presentations/java_mt_performance.pdf&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href="http://blogs.sun.com/jonthecollector/category/Java"&gt;http://blogs.sun.com/jonthecollector/category/Java&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.petefreitag.com/articles/gctuning/"&gt;http://www.petefreitag.com/articles/gctuning/&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href="http://www.md.pp.ru/~eu/jdk6options.html"&gt;http://www.md.pp.ru/~eu/jdk6options.html&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href="http://blogs.sun.com/watt/resource/jvm-options-list.html"&gt;http://blogs.sun.com/watt/resource/jvm-options-list.html&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href="http://alek.xspaces.org/2004/11/27/all-jvm-options"&gt;http://alek.xspaces.org/2004/11/27/all-jvm-options&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;P.D: Empiezan los Juegos. Que gane el mejor y que nadie se ahogue entre la polución de Pekín...&lt;strong&gt;&lt;/strong&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-7122429832825285823?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/7122429832825285823/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=7122429832825285823' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/7122429832825285823'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/7122429832825285823'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/08/jvm-tunning-parmetros-de-lanzamiento-de.html' title='JVM tuning: Parámetros de lanzamiento de JVM: Sun Hotspot'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_4ZEuwiCuF6A/SI9LsII24sI/AAAAAAAAAEM/Az9mkoTFfpk/s72-c/TuningRomania_0.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-1515262699747600278</id><published>2008-07-28T06:01:00.003+02:00</published><updated>2008-11-21T10:10:23.948+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Strings/Buffers/Ficheros'/><title type='text'>Comparativa de rendimiento en la lectura de ficheros</title><content type='html'>&lt;a href="http://nadeausoftware.com/sites/NadeauSoftware.com/files/JavaReadTimes_Zoom1.png"&gt;&lt;img style="FLOAT: right; MARGIN: 0px 0px 10px 10px; WIDTH: 320px; CURSOR: hand" alt="" src="http://nadeausoftware.com/sites/NadeauSoftware.com/files/JavaReadTimes_Zoom1.png" border="0" /&gt;&lt;/a&gt;A vueltas con el rendimiento en I/O :-)&lt;br /&gt;&lt;br /&gt;Este artículo y comparación es tremendamente interesante, sobre todo porque está documentado con datos de benchmarking aunque sobre un hardware particular, ojo. Las conclusiones son las de "casi siempre", pero para un tío oxidado como yo está bien que se meta la NIO entre las comparaciones. Y que se compare con C, que sigue ganando, je je.&lt;br /&gt;&lt;br /&gt;Sólo pegaré aquí las conclusiones, el resto debe leerse en el artículo original:&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;a href="http://nadeausoftware.com/articles/2008/02/java_tip_how_read_files_quickly"&gt;How read files quickly&lt;/a&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;em&gt;For the best Java read performance, there are four things to&lt;br /&gt;remember:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Minimize I/O operations by reading an array at a time, not a byte&lt;br /&gt;at a time. An 8Kbyte array is a good size.&lt;/li&gt;&lt;li&gt;Minimize method calls by getting&lt;br /&gt;data an array at a time, not a byte at a time. Use array indexing to get at&lt;br /&gt;bytes in the array.&lt;/li&gt;&lt;li&gt;Minimize thread synchronization locks if you don't need&lt;br /&gt;thread safety. Either make fewer method calls to a thread-safe class, or use a&lt;br /&gt;non-thread-safe class like &lt;code&gt;FileChannel&lt;/code&gt; and &lt;code&gt;MappedByteBuffer&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;Minimize data&lt;br /&gt;copying between the JVM/OS, internal buffers, and application arrays. Use&lt;br /&gt;&lt;code&gt;FileChannel&lt;/code&gt; with memory mapping, or a direct or wrapped array &lt;code&gt;ByteBuffer&lt;/code&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;/em&gt;&lt;/blockquote&gt;Si tuviera tiempo, me gustaría compararlo con una la versión "no sincornizada" de BufferedInputStream, para ver el impacto que en concreto introducen las regiones de exclusión mutua.&lt;br /&gt;&lt;br /&gt;Ubicación original del artículo: &lt;a href="http://nadeausoftware.com/articles/2008/02/java_tip_how_read_files_quickly"&gt;http://nadeausoftware.com/articles/2008/02/java_tip_how_read_files_quickly&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-1515262699747600278?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/1515262699747600278/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=1515262699747600278' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/1515262699747600278'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/1515262699747600278'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/07/comparativa-de-rendimiento-en-la.html' title='Comparativa de rendimiento en la lectura de ficheros'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-5842917603688511053</id><published>2008-07-23T05:40:00.002+02:00</published><updated>2008-11-21T10:26:21.952+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Strings/Buffers/Ficheros'/><category scheme='http://www.blogger.com/atom/ns#' term='Java CAPS'/><category scheme='http://www.blogger.com/atom/ns#' term='Memoria'/><title type='text'>Java CAPS: Optimización de transmisiones de ficheros</title><content type='html'>&lt;p&gt;&lt;a href="http://docs.sun.com/source/820-1277/images/RelationB2B_JCAPS.gif"&gt;&lt;img style="FLOAT: right; MARGIN: 0px 0px 10px 10px; WIDTH: 300px; CURSOR: hand" alt="" src="http://docs.sun.com/source/820-1277/images/RelationB2B_JCAPS.gif" border="0" /&gt;&lt;/a&gt;Java CAPS es el acrónimo de "&lt;strong&gt;Java Composite Aplications Platform Suite&lt;/strong&gt;". Es la suite completa de Sun aunando Integrador + ESB + EAI + BPEL PM + eTL + B2B. En realidad muchos de estos conceptos se difuminan unos con otros según quién los defina, así que es lógico que estén en una sola plataforma, aunque una organización tienda a usar sólo el 20-50% de su capacidad y potencia.&lt;/p&gt;&lt;p&gt;Y forma parte del Java Enterprise System, pero como producto independiente. y no es barato precisamente. Muy potente, pero muy desesperante muchas veces. Como sus competidores (Aqualogic, por ejemplo).&lt;/p&gt;&lt;p&gt;Como cualquier framework o integrador termendamente potente y tremendamente flexible, en muchos aspectos se ahorra tiempo de integración (con SAP, con SWIFT, con host, con MQ, con HL7......) y sobre todo de mantenimiento posterior, pero a cambio no esperemos el mejor rendimiento y tener el máximo control a bajo nivel. Toneladas de capas de encapsulación lo impiden.&lt;/p&gt;&lt;p&gt;Como otros entornos, &lt;strong&gt;Java CAPS&lt;/strong&gt; es de esos que te permite hacer las cosas mal y bien. Y por defecto, la opción rápida es hacerlas mal. Y la opción "no inmediata" es hacerlas bien. Es decir, leches, todo en memoria.&lt;/p&gt;&lt;p&gt;Y por duplicado muchas veces. Para variar.&lt;/p&gt;&lt;p&gt;Este artículo habla de cómo implementar comunicaciones FTP/FTPS/SFTP de forma "optimizada" para ficheros enormes. Sin más comentarios:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://blogs.sun.com/javacapsfieldtech/entry/streaming_large_ftp_transfers_with"&gt;http://blogs.sun.com/javacapsfieldtech/entry/streaming_large_ftp_transfers_with&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Más información sobre Java CAPS en la web oficial de Sun:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.sun.com/software/javaenterprisesystem/javacaps/index.jsp"&gt;http://www.sun.com/software/javaenterprisesystem/javacaps/index.jsp&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-5842917603688511053?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/5842917603688511053/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=5842917603688511053' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/5842917603688511053'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/5842917603688511053'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/06/optimizacin-de-transmisiones-de.html' title='Java CAPS: Optimización de transmisiones de ficheros'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-1075274966133364976</id><published>2008-07-19T19:27:00.019+02:00</published><updated>2008-12-10T12:55:14.648+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JDK/JVM'/><category scheme='http://www.blogger.com/atom/ns#' term='General'/><title type='text'>Oracle JRockit: malas noticias, se confirman las sospechas</title><content type='html'>&lt;img id="BLOGGER_PHOTO_ID_5222805381994510898" style="FLOAT: right; MARGIN: 0px 10px" alt="" src="http://3.bp.blogspot.com/_4ZEuwiCuF6A/SHsh0sTH-jI/AAAAAAAAAD8/xi8OJyo9I88/s400/rocket_crash_150x194.jpg" border="0" /&gt;(Actualizado el día 21 de julio y también el 19 de septiembre)&lt;br /&gt;&lt;br /&gt;Aquí está la noticia esperada, aunque no por ello menos horrible para la comunidad. Léase detenidamente, no obstante el resumen ejecutivo es que JRockit no va a ser un producto independiente, sino que estará incluido en los paquetes y productos comerciales de Oracle (Weblogics, Fussions, y otros).&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.oracle.com/technology/software/products/jrockit/FAQ.html"&gt;http://www.oracle.com/technology/software/products/jrockit/FAQ.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Puntos más significativos:&lt;/strong&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Sólo los clientes de Oracle lo pueden utilizar en producción (no sé si incluye la base de datos o sólo los productos de App Server / SOA). &lt;/li&gt;&lt;li&gt;Eso sí, puedes usar ese JRockit licenciado para ejecutar otros productos / servidores de aplicaciones que no sean de Oracle.&lt;/li&gt;&lt;li&gt;Desaparece la "redistributable license" para las nuevas versiones de JRockit. Vamos que no puedes empaquetar tus productos con JRockit incluido.&lt;/li&gt;&lt;li&gt;Sí sigue siendo gratuito y descargable (&lt;a href="http://www.oracle.com/technology/software/products/jrockit/index.html"&gt;http://www.oracle.com/technology/software/products/jrockit/index.html&lt;/a&gt;) para desarrollo y evaluación.&lt;/li&gt;&lt;/ul&gt;Es cierto que era una decisión previsible, conociendo la política comercial de Oracle. Y por otro lado es cierto que es discutible el beneficio en términos marketinianos y de posicionamiento de marca que implica tener un producto gratuito sobre el que dedicas toneladas de recursos internos de la compañía... ante eso hay dos posibilidades:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Abrir el producto para dedicar menos recursos a él y simbiosis con la comunidad "open Source"en esa misma. Es lo que ha hecho Sun con OpenJDK 7 (es discultible la tibieza de esta política, pero bueno).&lt;/li&gt;&lt;li&gt;Cobrar por el producto o incluirlo en otros productos comerciales. Es lo que ha hecho Oracle.&lt;/li&gt;&lt;/ul&gt;Vamos, y haciendo de "oráculo" ("Oracle" en inglés si se me permite el chiste fácil): R.I.P y también supondrá a largo plazo un frenazo a las mejoras en Hotspot, a no ser que se ponga las pilas la comunidad Open Source...&lt;br /&gt;&lt;br /&gt;Como puede verse, a nivel personal estoy contrariado, porque creo que básicamente esto elimina la competencia que había "entre los dos grandes" que ya comentamos en &lt;a href="http://serverperformance.blogspot.com/2008/06/sun-hotspot-vs-bea-jrockit.html"&gt;http://serverperformance.blogspot.com/2008/06/sun-hotspot-vs-bea-jrockit.html&lt;/a&gt;. Bueno, quizás IBM vuelva a recoger el guante pero lo dudo porque su política actual es un híbrido: JDK sin limitaciones para Linux, AIX y z/OS, pero en Windows sólo está disponible el JRE y sólo para máquinas IBM -controlado en BIOS- excepto un par de licencias para tests con Eclipse y para Apache Harmony... Para más información ver &lt;a href="http://www.ibm.com/developerworks/java/jdk/"&gt;http://www.ibm.com/developerworks/java/jdk/&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;En fin, tampoco gritemos esto muy alto porque los resultados empresariales de Sun en este semestre han sido horribles y hay rumores sobre el descontento de los accionistas sobre la política de "software gratis significa beneficios con el hardware" y quizás vientos de cambio que vete a saber...&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Corolario&lt;/strong&gt;: Al final va a resultar que la recomendación que hice en la entrada enlazada arriba (&lt;em&gt;"(...) mi opinión es que hoy en día hay que ser pragmático: si vas a ejecutar un Weblogic / Aqualogic, móntalo sobre JRockit; y si vas a ejecutar un Glassfish / JES / Java CAPS, hazlo sobre la JVM de Sun."&lt;/em&gt;) va a dejar de ser una recomendación sino una obligación, un mapa oficial de dependencias entre productos, licencias y hardware/software base. Es decir, habrá un par de JDKs abiertos y libres (&lt;a href="http://openjdk.java.net/"&gt;Open JDK&lt;/a&gt; por un lado y &lt;a href="http://harmony.apache.org/"&gt;Apache Harmony&lt;/a&gt; por el otro) y después cada sistema operativo y/o servidor de aplicaciones tendrá asociado un JDK específico de ese mismo fabricante. Y en realidad de facto ya es ese el panorama como hablábamos, véase los JDK de HP e IBM específicos para para ciertos sistemas operativos, y los JDK específicos para ciertos servidores de aplicaciones. Sólo falta que Sun tenga dos versiones de su JDK &lt;em&gt;et voilà&lt;/em&gt;..&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Aclaración:&lt;/strong&gt; Ojo que no soy ningún fan de Sun ni mucho menos, pero mira por lo menos me acaban de ahorrar tiempo para tomar cierta decisión...&lt;br /&gt;&lt;br /&gt;P.D: Y otro chiste fácil y viejo... "ORACLE" al revés se lee "EL CARO" :-) &lt;em&gt;[For those using automatic translators: this is a pun in Spanish: "O-R-A-C-L-E" =&gt; "E-L-C-A-R-O", meaning "THE EXPENSIVE ONE"]&lt;/em&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Actualización 19/9/2008: Unos meses después, parece que las aguas han vuelto a su cauce y se ha normalizado la política de Oracle respecto a los productos de Bea, al menos vuelve a haber blogs corporativos y la gente de JRockit parece activa y trabajando en distintas líneas nuevas...&lt;/em&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-1075274966133364976?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/1075274966133364976/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=1075274966133364976' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/1075274966133364976'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/1075274966133364976'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/07/oracle-jrockit-malas-noticias-se.html' title='Oracle JRockit: malas noticias, se confirman las sospechas'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_4ZEuwiCuF6A/SHsh0sTH-jI/AAAAAAAAAD8/xi8OJyo9I88/s72-c/rocket_crash_150x194.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-8979387376951798353</id><published>2008-07-14T06:49:00.006+02:00</published><updated>2008-12-10T12:55:14.851+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Strings/Buffers/Ficheros'/><category scheme='http://www.blogger.com/atom/ns#' term='Sincronización'/><category scheme='http://www.blogger.com/atom/ns#' term='Memoria'/><title type='text'>Buffers inteligentes con swap a disco, o "a prueba de tontos"</title><content type='html'>&lt;a href="http://3.bp.blogspot.com/_4ZEuwiCuF6A/SFZ7MmH8s7I/AAAAAAAAAC0/eUgyljdRcFY/s1600-h/sun_5.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5212489075050460082" style="FLOAT: right; MARGIN: 0px 0px 10px 10px; CURSOR: hand" alt="" src="http://3.bp.blogspot.com/_4ZEuwiCuF6A/SFZ7MmH8s7I/AAAAAAAAAC0/eUgyljdRcFY/s320/sun_5.jpg" border="0" /&gt;&lt;/a&gt; Entramos en modo paja mental, siguiendo lo que introduje en la anterior entrada &lt;a href="http://serverperformance.blogspot.com/search/label/Buffers)"&gt;"Buffers: por defecto y por exceso"&lt;/a&gt;. &lt;p&gt;De forma recurrente, vienen a mi dos necesidades / problemas típicos, que pueden resolverse de forma elegante a la vez. Dos por uno. Mierda para cada uno.&lt;/p&gt;&lt;p&gt;A saber:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Dado un &lt;code&gt;OutputStream&lt;/code&gt; sobre el que mi código va escribiendo quiero ser capaz de obtener de forma elegante el &lt;code&gt;InputStream&lt;/code&gt;. Sin mucha sintaxis, sin crear programáticamente ficheros temporales o hacer cosas raras con arrays de bytes. Ni con extraños modelos de pipelining. Pensando en un uso single-thread. ¿Por qué? Porque yo lo valgo. Y porque Murphy dice que si tienes un &lt;code&gt;OutputStream&lt;/code&gt; invocarás a un método que necesite como parámetro un &lt;code&gt;InputStream&lt;/code&gt;. Y viceversa.&lt;/li&gt;&lt;li&gt;Y mucho más importante: ¿cuántas veces hemos dicho lo malos malísimos que son los arrays de bytes? ¿es que no somos conscientes de que potencialmetne son un cúmulo de bichos? ¿que se volverán contra nosotros en cualquier momento del futuro, cuando estamos pensando ya en otras cosas?&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Es inimaginable cómo se abusa en general del uso de array de bytes. Y no me refiero sólo a los típicos gazapos de un programador que empieza. Me estoy refiriendo a diseños internos de productos de reconocido prestigio tanto a nivel nacional o internacional (y no señalaré a nadie). &lt;/p&gt;&lt;p&gt;En alguna otra ocasión hemos hablado de que sería maravilloso que la gestión de memoria en Java soportara algún tipo de nuevo modelo de memoria, separada de los heaps y permgens y todo eso, sobre el que pudiera hacerse swap a disco sin problema. Sé que ya es suficientemente compleja (eden, survivor space, permanent) pero sería genial que la propia JVM detecte el uso de arrays / buffers grandes, o que fuera configurable, y que permitiera hacer swapping a disco de todo o parte de él independientemente de en qué zona de memoria resida.&lt;/p&gt;&lt;p&gt;Pero mientras no sea así, también podemos hacerlo nosotros. La encapsulación al poder. Dejo aquí un código fuente que hice en 2003, allá por los tiempos del JDK 1.3 y 1.4 (creo :-), que básicamene encapsula eso: funciona como un ByteArrayOutputStream de esos que gustan tanto a los programadores, pero en cuanto pasa de un cierto tamaño máximo, swapea a disco. Y además permite recoger un InputStream para hacer pipelines dentro de un solo thread. Por cierto, sin regiones de exclusión mutua porque está pensado para ser usado en un solo thread.&lt;/p&gt;&lt;p&gt;Es decir, un mecanismo "automático" para balancear alto rendimiento y alta escalabilidad: rendimiento en el tratamiento de streams cuando estos son de un tamaño aceptable (todo en memoria), y escalabilidad porque limita el abuso de la memoria como recurso en caso de que algún elemento se nos vaya de las manos.&lt;/p&gt;&lt;p&gt;¿Usos? Más de los que pueden parecer en un principio, por ejemplo intercambio de información entre procesos/colaboraciones desacopladas, para tratar optimizadamente peticiones SOAP con grandes ficheros como parámetros, generación y tratamiento de imágenes o PDFs o Excels en servidor, uso como elemento temporal "optimizado" por ejemplo en un GZIPFilter (si el tamaño comprimido es pequeño, se usa buffer en memoria, si es grande se usa buffer en disco para no consumir excesiva), etc.&lt;/p&gt;&lt;p&gt;Ahí va el código fuente:&lt;/p&gt;&lt;blockquote&gt;&lt;code&gt;&lt;br /&gt;package org.serverperformance.io;&lt;br /&gt;&lt;br /&gt;import java.io.File;&lt;br /&gt;import java.io.BufferedInputStream;&lt;br /&gt;import java.io.ByteArrayInputStream;&lt;br /&gt;import java.io.OutputStream;&lt;br /&gt;import java.io.InputStream;&lt;br /&gt;import java.io.IOException;&lt;br /&gt;import java.io.FileInputStream;&lt;br /&gt;import java.io.FileOutputStream;&lt;br /&gt;&lt;br /&gt;&lt;em&gt;/**&lt;br /&gt;* Equivale a un ByteArrayOutputStream con las siguientes características especiales:&lt;br /&gt;*   - El buffer sólo consume 32 KBytes de heap (configurable, en caso de requerir más,&lt;br /&gt;*     utiliza el disco per nunca consume más heap que el marcado.&lt;br /&gt;*   - Métodos getInputStream() y writeTo(OutputStream) para facilitar las&lt;br /&gt;*     conversiones (típico al invocar métodos de JDBC que requieren InputStreams, mientras&lt;br /&gt;*     que la información se va escribiendo en un OutputStream&lt;br /&gt;*   - Se añade un método write(InputStream) que escribe en este stream de salida todo el&lt;br /&gt;*     contenido del stream de entrada.&lt;br /&gt;*   - A diferencia que ByteArrayOutputStream, el método close() también libera recursos en memoria.&lt;br /&gt;*&lt;br /&gt;* El código fuente está basado en java.io.BufferedOutputStream, con los añadidos&lt;br /&gt;* necesarios y quitando las regiones de exclusión mutua.&lt;br /&gt;*&lt;br /&gt;* @author "Server Performance" &lt;a href="http://serverperformance.blogspot.com/"&gt;http://serverperformance.blogspot.com&lt;/a&gt;&lt;br /&gt;* @author (Basado en) &lt;a href="http://java.sun.com/"&gt;http://java.sun.com&lt;/a&gt;&lt;br /&gt;* @version 1.1, 30/06/03&lt;br /&gt;*/&lt;/em&gt;&lt;br /&gt;public class &lt;strong&gt;IntelligentBufferedOutputStream&lt;/strong&gt; extends OutputStream {&lt;br /&gt;&lt;br /&gt;  private final static int DEFAULT_BUFFER_SIZE = 32*1024;&lt;br /&gt;  private final static String TEMP_FILE_PREFIX = "temp_buff_serverperformance_";&lt;br /&gt;  private final static String TEMP_FILE_SUFFIX = ".tmp";&lt;br /&gt;&lt;br /&gt;  &lt;em&gt;/**&lt;br /&gt;  * The output stream to the underlying temp file.&lt;br /&gt;  */&lt;/em&gt;&lt;br /&gt;  protected OutputStream out;&lt;br /&gt;  protected InputStream in;&lt;br /&gt;&lt;br /&gt;  &lt;em&gt;/**&lt;br /&gt;  * The underlying temporal file.&lt;br /&gt;  */&lt;/em&gt;&lt;br /&gt;  protected File tempFile;&lt;br /&gt;&lt;br /&gt;  protected boolean usedTempFile = false;&lt;br /&gt;&lt;br /&gt;  &lt;em&gt;/**&lt;br /&gt;  * The internal buffer where data is stored.&lt;br /&gt;  */&lt;/em&gt;&lt;br /&gt;  protected byte buf[];&lt;br /&gt;&lt;br /&gt;  &lt;em&gt;/**&lt;br /&gt;  * The number of valid bytes in the buffer. This value is always&lt;br /&gt;  * in the range &lt;tt&gt;0&lt;/tt&gt; through &lt;tt&gt;buf.length&lt;/tt&gt;; elements&lt;br /&gt;  * &lt;tt&gt;buf[0]&lt;/tt&gt; through &lt;tt&gt;buf[count-1]&lt;/tt&gt; contain valid&lt;br /&gt;  * byte data.&lt;br /&gt;  */&lt;/em&gt;&lt;br /&gt;  protected int count;&lt;br /&gt;&lt;br /&gt;  protected boolean deleteTempFileOnClose = true;&lt;br /&gt;&lt;br /&gt;  &lt;em&gt;/**&lt;br /&gt;  * Creates a new buffered output stream to write data to the&lt;br /&gt;  * specified underlying output stream with a default 32-kbyte&lt;br /&gt;  * buffer size.&lt;br /&gt;  *&lt;br /&gt;  * @author "Server Performance" &lt;a href="http://serverperformance.blogspot.com/"&gt;http://serverperformance.blogspot.com&lt;/a&gt;&lt;br /&gt;  */&lt;/em&gt;&lt;br /&gt;  public &lt;strong&gt;IntelligentBufferedOutputStream&lt;/strong&gt;() throws IOException {&lt;br /&gt;    this(DEFAULT_BUFFER_SIZE, true);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  &lt;em&gt;/**&lt;br /&gt;  * Creates a new buffered output stream to write data to the&lt;br /&gt;  * specified underlying output stream with a default buffer size.&lt;br /&gt;  *&lt;br /&gt;  * @author "Server Performance" &lt;a href="http://serverperformance.blogspot.com/"&gt;http://serverperformance.blogspot.com&lt;/a&gt;&lt;br /&gt;  */&lt;/em&gt;&lt;br /&gt;  public &lt;strong&gt;IntelligentBufferedOutputStream&lt;/strong&gt;(boolean deleteTempFileOnClose) throws IOException {&lt;br /&gt;    this(DEFAULT_BUFFER_SIZE, deleteTempFileOnClose);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  &lt;em&gt;/**&lt;br /&gt;  * Creates a new buffered output stream to write data to the&lt;br /&gt;  * specified underlying output stream with the specified buffer&lt;br /&gt;  * size.&lt;br /&gt;  *&lt;br /&gt;  * @param size the buffer size.&lt;br /&gt;  * @exception IllegalArgumentException if size &lt;= 0.   * @author "Server Performance" &lt;a href="http://serverperformance.blogspot.com/"&gt;http://serverperformance.blogspot.com&lt;/a&gt;&lt;br /&gt;  */&lt;/em&gt;&lt;br /&gt;  public &lt;strong&gt;IntelligentBufferedOutputStream&lt;/strong&gt;(int size, boolean deleteTempFileOnClose) throws IOException {&lt;br /&gt;    this.buf = new byte[size];&lt;br /&gt;    this.deleteTempFileOnClose = deleteTempFileOnClose;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  &lt;em&gt;/** Obtiene un InputStream, bien un BufferedInputStream del fichero temporal, bien&lt;br /&gt;  * un ByteArrayInputStream del buffer en memoria (según el caso).&lt;br /&gt;  *&lt;br /&gt;  * @author "Server Performance" &lt;a href="http://serverperformance.blogspot.com/"&gt;http://serverperformance.blogspot.com&lt;/a&gt;&lt;br /&gt;  */&lt;/em&gt;&lt;br /&gt;  public InputStream &lt;strong&gt;getInputStream()&lt;/strong&gt; throws IOException {&lt;br /&gt;    if (in==null) {&lt;br /&gt;      if (usedTempFile) {&lt;br /&gt;        flushBufferToFile();&lt;br /&gt;        in = new BufferedInputStream(new FileInputStream(tempFile),buf.length);&lt;br /&gt;      }&lt;br /&gt;      else {&lt;br /&gt;        in = new ByteArrayInputStream(buf,0,count);&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;    return in;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  &lt;em&gt;/** Copia el contenido del buffer (en memoria o en disco) a otro OutputStream.&lt;br /&gt;  *&lt;br /&gt;  * @author "Server Performance" &lt;a href="http://serverperformance.blogspot.com/"&gt;http://serverperformance.blogspot.com&lt;/a&gt;&lt;br /&gt;  */&lt;/em&gt;&lt;br /&gt;  public void &lt;strong&gt;writeTo&lt;/strong&gt;(OutputStream target) throws IOException {&lt;br /&gt;    &lt;em&gt;// El tamaño del buffer temporal... pues el mismo que el original&lt;/em&gt;&lt;br /&gt;    byte[] tempBuf = new byte[buf.length];&lt;br /&gt;    getInputStream();&lt;br /&gt;    int readedLen;&lt;br /&gt;    while ((readedLen = in.read(tempBuf)) &gt; 0) {&lt;br /&gt;      target.write(tempBuf, 0, readedLen);&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  &lt;em&gt;/** Flush the internal buffer&lt;br /&gt;  *&lt;br /&gt;  * @author "Server Performance" &lt;a href="http://serverperformance.blogspot.com/"&gt;http://serverperformance.blogspot.com&lt;/a&gt;&lt;br /&gt;  */&lt;/em&gt;&lt;br /&gt;  private void &lt;strong&gt;flushBufferToFile()&lt;/strong&gt; throws IOException {&lt;br /&gt;    &lt;em&gt;// Si no estaba creado, crea el fichero temporal&lt;/em&gt;&lt;br /&gt;    if (!usedTempFile) {&lt;br /&gt;      tempFile = File.createTempFile(TEMP_FILE_PREFIX,TEMP_FILE_SUFFIX,null);&lt;br /&gt;      try {&lt;br /&gt;        tempFile.deleteOnExit();&lt;br /&gt;      }&lt;br /&gt;      catch (Throwable ignored) {}&lt;br /&gt;      out = new FileOutputStream(tempFile);&lt;br /&gt;      usedTempFile = true;&lt;br /&gt;    }&lt;br /&gt;    if (count &gt; 0) {&lt;br /&gt;      &lt;em&gt;// Flush to disk!&lt;/em&gt;&lt;br /&gt;      out.write(buf, 0, count);&lt;br /&gt;      out.flush();;&lt;br /&gt;      count = 0;&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  &lt;em&gt;/**&lt;br /&gt;  * Consumes from de specified InputStream and writes into this buffered output stream.&lt;br /&gt;  * ¡OJO! no cierra el inputstream, debe cerrarlo el invocante...&lt;br /&gt;  *&lt;br /&gt;  * @param in the origin/producer of the data.&lt;br /&gt;  * @exception IOException if an I/O error occurs.&lt;br /&gt;  *&lt;br /&gt;  * @author "Server Performance" &lt;a href="http://serverperformance.blogspot.com/"&gt;http://serverperformance.blogspot.com&lt;/a&gt;&lt;br /&gt;  * @author (Basado en) &lt;a href="http://java.sun.com/"&gt;http://java.sun.com&lt;/a&gt;&lt;br /&gt;  */&lt;/em&gt;&lt;br /&gt;  public &lt;em&gt;/*synchronized*/&lt;/em&gt; void &lt;strong&gt;write&lt;/strong&gt;(InputStream in) throws IOException {&lt;br /&gt;    byte[] bufLectura = new byte[buf.length];&lt;br /&gt;    int len;&lt;br /&gt;    while ((len = in.read(bufLectura)) &gt; 0) {&lt;br /&gt;      write(bufLectura, 0, len);&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  &lt;em&gt;/**&lt;br /&gt;  * Writes the specified byte to this buffered output stream.&lt;br /&gt;  *&lt;br /&gt;  * @param b the byte to be written.&lt;br /&gt;  * @exception IOException if an I/O error occurs.&lt;br /&gt;  *&lt;br /&gt;  * @author "Server Performance" &lt;a href="http://serverperformance.blogspot.com/"&gt;http://serverperformance.blogspot.com&lt;/a&gt;&lt;br /&gt;  * @author (Basado en) &lt;a href="http://java.sun.com/"&gt;http://java.sun.com&lt;/a&gt;&lt;br /&gt;  */&lt;/em&gt;&lt;br /&gt;  public &lt;em&gt;/*synchronized*/&lt;/em&gt; void &lt;strong&gt;write&lt;/strong&gt;(int b) throws IOException {&lt;br /&gt;    if (count &gt;= buf.length) {&lt;br /&gt;      flushBufferToFile();&lt;br /&gt;    }&lt;br /&gt;    buf[count++] = (byte)b;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  &lt;em&gt;/**&lt;br /&gt;  * Writes &lt;code&gt;len&lt;/code&gt; bytes from the specified byte array&lt;br /&gt;  * starting at offset &lt;code&gt;off&lt;/code&gt; to this buffered output stream.&lt;br /&gt;  *&lt;br /&gt;  * Ordinarily this method stores bytes from the given array into this&lt;br /&gt;  * stream's buffer, flushing the buffer to the underlying output stream as&lt;br /&gt;  * needed. If the requested length is at least as large as this stream's&lt;br /&gt;  * buffer, however, then this method will flush the buffer and write the&lt;br /&gt;  * bytes directly to the underlying output stream. Thus redundant&lt;br /&gt;  * &lt;code&gt;BufferedTempFileOutputStream&lt;/code&gt;s will not copy data unnecessarily.&lt;br /&gt;  *&lt;br /&gt;  * @param b the data.&lt;br /&gt;  * @param off the start offset in the data.&lt;br /&gt;  * @param len the number of bytes to write.&lt;br /&gt;  * @exception IOException if an I/O error occurs.&lt;br /&gt;  *&lt;br /&gt;  * @author "Server Performance" &lt;a href="http://serverperformance.blogspot.com/"&gt;http://serverperformance.blogspot.com&lt;/a&gt;&lt;br /&gt;  * @author (Basado en) &lt;a href="http://java.sun.com/"&gt;http://java.sun.com&lt;/a&gt;&lt;br /&gt;  */&lt;/em&gt;&lt;br /&gt;  public &lt;em&gt;/*synchronized*/&lt;/em&gt; void &lt;strong&gt;write&lt;/strong&gt;(byte b[], int off, int len) throws IOException {&lt;br /&gt;    if (len &gt;= buf.length) {&lt;br /&gt;      /* If the request length exceeds the size of the output buffer,&lt;br /&gt;        flush the output buffer and then write the data directly.&lt;br /&gt;        In this way buffered streams will cascade harmlessly. */&lt;br /&gt;      flushBufferToFile();&lt;br /&gt;      out.write(b, off, len);&lt;br /&gt;      return;&lt;br /&gt;    }&lt;br /&gt;    if (len &gt; buf.length - count) {&lt;br /&gt;      flushBufferToFile();&lt;br /&gt;    }&lt;br /&gt;    System.arraycopy(b, off, buf, count, len);&lt;br /&gt;    count += len;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  &lt;em&gt;/**&lt;br /&gt;  * Flushes this buffered output stream. This forces any buffered&lt;br /&gt;  * output bytes to be written out to the underlying output stream.&lt;br /&gt;  *&lt;br /&gt;  * @exception IOException if an I/O error occurs.&lt;br /&gt;  * @see java.io.OutputStream#out&lt;br /&gt;  *&lt;br /&gt;  * @author "Server Performance" &lt;a href="http://serverperformance.blogspot.com/"&gt;http://serverperformance.blogspot.com&lt;/a&gt;&lt;br /&gt;  * @author (Basado en) &lt;a href="http://java.sun.com/"&gt;http://java.sun.com&lt;/a&gt;&lt;br /&gt;  */&lt;/em&gt;&lt;br /&gt;  public &lt;em&gt;/*synchronized*/&lt;/em&gt; void &lt;strong&gt;flush&lt;/strong&gt;() throws IOException {&lt;br /&gt;    if (usedTempFile) {&lt;br /&gt;      flushBufferToFile();&lt;br /&gt;      out.flush();&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  &lt;em&gt;/**&lt;br /&gt;  * Writes &lt;code&gt;b.length&lt;/code&gt; bytes to this output stream.&lt;br /&gt;  *&lt;br /&gt;  * The &lt;code&gt;write&lt;/code&gt; method of &lt;code&gt;OutputStream&lt;/code&gt;&lt;br /&gt;  * calls its &lt;code&gt;write&lt;/code&gt; method of three arguments with the&lt;br /&gt;  * arguments &lt;code&gt;b&lt;/code&gt;, &lt;code&gt;0&lt;/code&gt;, and&lt;br /&gt;  * &lt;code&gt;b.length&lt;/code&gt;.&lt;br /&gt;  *&lt;br /&gt;  * Note that this method does not call the one-argument&lt;br /&gt;  * &lt;code&gt;write&lt;/code&gt; method of its underlying stream with the single&lt;br /&gt;  * argument &lt;code&gt;b&lt;/code&gt;.&lt;br /&gt;  *&lt;br /&gt;  * @param b the data to be written.&lt;br /&gt;  * @exception IOException if an I/O error occurs.&lt;br /&gt;  * @see java.io.OutputStream#write(byte[], int, int)&lt;br /&gt;  *&lt;br /&gt;  * @author "Server Performance" &lt;a href="http://serverperformance.blogspot.com/"&gt;http://serverperformance.blogspot.com&lt;/a&gt;&lt;br /&gt;  * @author (Basado en) &lt;a href="http://java.sun.com/"&gt;http://java.sun.com&lt;/a&gt;&lt;br /&gt;  */&lt;/em&gt;&lt;br /&gt;  public void &lt;strong&gt;write&lt;/strong&gt;(byte b[]) throws IOException {&lt;br /&gt;    write(b, 0, b.length);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  &lt;em&gt;/**&lt;br /&gt;  * Closes this output stream and releases any system resources&lt;br /&gt;  * associated with the stream, including the memory buffer.&lt;br /&gt;  *&lt;br /&gt;  Also, delete the temporal file if so marked.&lt;br /&gt;  *&lt;br /&gt;  * @exception IOException if an I/O error occurs.&lt;br /&gt;  * @see java.io.OutputStream#flush()&lt;br /&gt;  * @see java.io.OutputStream#out&lt;br /&gt;  *&lt;br /&gt;  * @author "Server Performance" &lt;a href="http://serverperformance.blogspot.com/"&gt;http://serverperformance.blogspot.com&lt;/a&gt;&lt;br /&gt;  * @author (Basado en) &lt;a href="http://java.sun.com/"&gt;http://java.sun.com&lt;/a&gt;&lt;br /&gt;  */&lt;/em&gt;&lt;br /&gt;  public void &lt;strong&gt;close()&lt;/strong&gt; throws IOException {&lt;br /&gt;    &lt;em&gt;// Libera recursos del fichero temporal&lt;/em&gt;&lt;br /&gt;    if (usedTempFile) {&lt;br /&gt;      flushBufferToFile();&lt;br /&gt;      try {&lt;br /&gt;        &lt;em&gt;//if (out!=null) no puede ser nulo después de flushBufferToFile()&lt;/em&gt;&lt;br /&gt;          out.close();&lt;br /&gt;          out = null;&lt;br /&gt;      }&lt;br /&gt;      catch (Throwable ignored) {}&lt;br /&gt;      try {&lt;br /&gt;        if (in!=null)&lt;br /&gt;          in.close();&lt;br /&gt;          in = null;&lt;br /&gt;      }&lt;br /&gt;      catch (Throwable ignored) {}&lt;br /&gt;      if (deleteTempFileOnClose) {&lt;br /&gt;        try {&lt;br /&gt;          &lt;em&gt;// Borra el fichero temporal.&lt;br /&gt;          // Aunque está marcado para ser borrado al cerrar la JVM,&lt;br /&gt;          // por seguridad y optimización de recursos, lo hago ya&lt;/em&gt;&lt;br /&gt;          tempFile.delete();&lt;br /&gt;        }&lt;br /&gt;        catch (Throwable ignored) {}&lt;br /&gt;      }&lt;br /&gt;      if (deleteTempFileOnClose) {&lt;br /&gt;        try {&lt;br /&gt;          &lt;em&gt;// Borra el fichero temporal.&lt;br /&gt;          // Aunque está marcado para ser borrado al cerrar la JVM,&lt;br /&gt;          // por seguridad y optimización de recursos, lo hago ya&lt;/em&gt;&lt;br /&gt;          tempFile.delete();&lt;br /&gt;        }&lt;br /&gt;        catch (Throwable ignored) {}&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;    &lt;em&gt;// Libera recursos en memoria&lt;/em&gt;&lt;br /&gt;    buf = null;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  &lt;em&gt;/** Returns the total buffer size&lt;br /&gt;  &lt;br /&gt;  * @author "Server Performance" &lt;a href="http://serverperformance.blogspot.com/"&gt;http://serverperformance.blogspot.com&lt;/a&gt;&lt;br /&gt;  * @author (Basado en) &lt;a href="http://java.sun.com/"&gt;http://java.sun.com&lt;/a&gt;&lt;br /&gt;  */&lt;/em&gt;&lt;br /&gt;  public int &lt;strong&gt;size&lt;/strong&gt;() throws IOException {&lt;br /&gt;    if (usedTempFile) {&lt;br /&gt;      flushBufferToFile();&lt;br /&gt;      return (int)tempFile.length();&lt;br /&gt;    }&lt;br /&gt;    else {&lt;br /&gt;      return count;&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  &lt;em&gt;/**&lt;br /&gt;  * @author "Server Performance" &lt;a href="http://serverperformance.blogspot.com/"&gt;http://serverperformance.blogspot.com&lt;/a&gt;&lt;br /&gt;  */&lt;/em&gt;&lt;br /&gt;  public void &lt;strong&gt;closeAndDelete&lt;/strong&gt;() throws IOException {&lt;br /&gt;    boolean oldFlag = deleteTempFileOnClose;&lt;br /&gt;    deleteTempFileOnClose = true;&lt;br /&gt;    close();&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  &lt;em&gt;/**&lt;br /&gt;  * @author "Server Performance" &lt;a href="http://serverperformance.blogspot.com/"&gt;http://serverperformance.blogspot.com&lt;/a&gt;&lt;br /&gt;  */&lt;/em&gt;&lt;br /&gt;  public void &lt;strong&gt;finalize&lt;/strong&gt;() {&lt;br /&gt;    &lt;em&gt;// Por si acaso...&lt;br /&gt;    (en las clases de java.io también lo hace...)&lt;/em&gt;&lt;br /&gt;    try {&lt;br /&gt;      flush();&lt;br /&gt;      close();&lt;br /&gt;    }&lt;br /&gt;    catch (Throwable ignored) {}&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;}&lt;/code&gt; &lt;p&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;En cualquier caso, como muchas otras encapsulaciones, es algo que (al menos a mi) me parece una gran idea pero que en una Organización suele terminar no utilizándose por desconocimiento o por complejidad, o porque es un conocimiento que se pierde, o porque estaba mal documentado, o porque los procedimientos internos de comunicación eran más bien pobres hace unos años.&lt;/p&gt;&lt;p&gt;Es decir, es un código ideal para "núcleos" y componentes muy concretos, y quizás poco más.&lt;/p&gt;&lt;p&gt;En mi anterior vida, desde 2003 hasta hace unos meses, creo que este código se usado sólo en tres situaciones y me he quitado la espinita de encima porque en mi actual vida un invento de encapsulamiento muy similar a este nos ha salvado la vida en un caso muy concreto de invocaciones a módulos desacoplados donde podían darse situaciones de lo más diversa. &lt;/p&gt;&lt;p&gt;:-)&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-8979387376951798353?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/8979387376951798353/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=8979387376951798353' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/8979387376951798353'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/8979387376951798353'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/07/buffers-inteligentes-con-swap-disco-o.html' title='Buffers inteligentes con swap a disco, o &quot;a prueba de tontos&quot;'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_4ZEuwiCuF6A/SFZ7MmH8s7I/AAAAAAAAAC0/eUgyljdRcFY/s72-c/sun_5.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-3588234718848640638</id><published>2008-07-10T15:04:00.006+02:00</published><updated>2008-11-21T10:28:10.586+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JDK/JVM'/><title type='text'>Java SE 6u6p Performance Release</title><content type='html'>&lt;p style="FONT-STYLE: italic"&gt;[Notas de octubre'08 y noviembre'08 ==&gt;&lt;/p&gt;&lt;p style="FONT-STYLE: italic"&gt;Querido googler: si llegas a esta página -como muchos- buscando información de las performance releases del JRE 6, quizás te interesen los artículos posteriores &lt;a href="http://serverperformance.blogspot.com/2008/08/java-se-6u6-p-performance-release-ya.html"&gt;Java SE 6u6-p Performance Release - YA DISPONIBLE EN OTRAS PLATAFORMAS&lt;/a&gt;, &lt;a href="http://serverperformance.blogspot.com/2008/09/6u6-p-pues-en-linux-x64-peta.html"&gt;6u6-p: Pues en Linux x64 peta!!!!!!!&lt;/a&gt; y &lt;a href="http://serverperformance.blogspot.com/2008/11/identificacin-de-bugs-en-la-versin-6u6p.html"&gt;Identificación de bugs en la versión 6u6p y workaround&lt;/a&gt; ]&lt;/p&gt;&lt;br /&gt;Nueva actualización de rendimiento en Java 6. Continuando con lo comentado en la entrada &lt;a href="http://serverperformance.blogspot.com/2008/06/java-se-6u5p-performance-release.html"&gt;Java SE 6u5p Performance Release&lt;/a&gt;, en julio Sun ha liberado ya la siguiente vuelta de tuerca: &lt;strong&gt;"JDK 6 Update 6 Performance Release"&lt;/strong&gt; para plataformas SPARC. Del blog de David Dagastine: &lt;blockquote&gt;&lt;em&gt;I'm please to announce the release of JDK 6 Update 6 Performance Release on SPARC platforms. This is the latest of our performance releases and is the culmination of our optimization efforts over the last year. With this JDK Sun achieved many world records on SPECjappserver2004, SPECweb2005, SPECjbb2005, and the first ever SPECjvm2008 submission.&lt;/em&gt;&lt;/blockquote&gt;En breve estará disponible también para x64, aunque todavía no. Entre otras novedades, han mejorado el rendimiento en la clase TreeMap gracias a la aportación del equipo de Apache Harmony.&lt;br /&gt;&lt;br /&gt;Referencias:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://blogs.sun.com/dagastine/entry/jdk_6_update_6_performance"&gt;http://blogs.sun.com/dagastine/entry/jdk_6_update_6_performance&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blogs.sun.com/dagastine/entry/apache_harmony_thanks_for_the"&gt;http://blogs.sun.com/dagastine/entry/apache_harmony_thanks_for_the&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://java.sun.com/javase/technologies/performance.jsp"&gt;http://java.sun.com/javase/technologies/performance.jsp&lt;/a&gt; (entrada de julio'08)&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-3588234718848640638?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/3588234718848640638/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=3588234718848640638' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/3588234718848640638'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/3588234718848640638'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/07/java-se-6u6p-performance-release.html' title='Java SE 6u6p Performance Release'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-5762228473491334349</id><published>2008-07-07T03:37:00.005+02:00</published><updated>2008-11-21T10:26:58.313+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='General'/><title type='text'>Daytona Terabyte: Yahoo! gana la competición de rendimiento 2008 utilizando Apache Hadoop</title><content type='html'>&lt;p&gt;&lt;em&gt;No comment&lt;/em&gt;, aunque debería añadirlo también al post sobre mitos caídos...:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.javahispano.org/contenidos/es/hadoop_gana_competicion_de_ordenacion/?menuId=NEWS"&gt;http://www.javahispano.org/contenidos/es/hadoop_gana_competicion_de_ordenacion/?menuId=NEWS&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.hpl.hp.com/hosted/sortbenchmark/"&gt;http://www.hpl.hp.com/hosted/sortbenchmark/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.hpl.hp.com/hosted/sortbenchmark/YahooHadoop.pdf"&gt;http://www.hpl.hp.com/hosted/sortbenchmark/YahooHadoop.pdf&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://hadoop.apache.org/"&gt;http://hadoop.apache.org/&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;P.D: Como esto del "Java vs C++" es como lo del Madrid y el Barça (como tantas otras cosas, ver el artículo &lt;a href="http://serverperformance.blogspot.com/2008/06/sun-hotspot-vs-bea-jrockit.html"&gt;Sun Hotspot -vs- Bea JRockit&lt;/a&gt;), es decir que no puedes cambiar de opinión, se lo pasé a uno que me sé yo y su respuesta ha sido darles mérito a los ingenieros y programadores (&lt;em&gt;"Tiene merito la cosa, han optimizado los algoritmos incluso para ganar desarrollándolo en java..."&lt;/em&gt;). Interesante reflexión :-)&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://hadoop.apache.org/"&gt;&lt;img style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://hadoop.apache.org/images/hadoop-logo.jpg" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-5762228473491334349?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/5762228473491334349/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=5762228473491334349' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/5762228473491334349'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/5762228473491334349'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/07/daytona-terabyte-yahoo-gana-la.html' title='Daytona Terabyte: Yahoo! gana la competición de rendimiento 2008 utilizando Apache Hadoop'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-8787935917561327289</id><published>2008-07-03T23:39:00.006+02:00</published><updated>2009-03-18T17:41:33.644+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Sincronización'/><category scheme='http://www.blogger.com/atom/ns#' term='Memoria'/><title type='text'>"Double checked locking" por fin funciona en Java</title><content type='html'>&lt;a href="http://3.bp.blogspot.com/_4ZEuwiCuF6A/SFeNLcNUusI/AAAAAAAAADE/YCAAduI4sNA/s1600-h/ico_lock_smiley.gif"&gt;&lt;img style="MARGIN: 0px 10px 10px 0px; FLOAT: left; CURSOR: hand" id="BLOGGER_PHOTO_ID_5212790321394793154" border="0" alt="" src="http://3.bp.blogspot.com/_4ZEuwiCuF6A/SFeNLcNUusI/AAAAAAAAADE/YCAAduI4sNA/s400/ico_lock_smiley.gif" /&gt;&lt;/a&gt;&lt;em&gt;[Actualización noviembre 2008: referencia al final del post a un nuevo artículo de Jeremy "mascando" las variables volátiles en Java] &lt;/em&gt;&lt;br /&gt;&lt;br /&gt;Es de todos conocido (espero) el pernicioso o impredecible efecto en Java del uso de la optimización "&lt;strong&gt;double-checked locking&lt;/strong&gt;" tan usada en otros lenguajes como C++. El problema básicamente se da por dos motivos: en entornos multi-core / multi-procesador la JVM puede decidir que los threads utilicen copias locales de los punteros e incluso de algunas variables pequeñas para mejorar el rendimiento de acceso (las copias locales de la variable que tiene cada thread pueden no darse por enteradas del cambio global en condiciones de stress), aparte de que el compilador puede cambiar el orden de ejecución de algunas sentencias... :-(&lt;br /&gt;&lt;br /&gt;Pero, desde J2SE 1.5, &lt;strong&gt;existe solución al problema&lt;/strong&gt; añadiendo la palabra clave "volatile" como modificador de la variable que se utiliza como monitor, lo que asegura que todos los threads vean la misma versión de dicha variable, sin usar copias locales. Se penaliza muy levemente el rendimiento de acceso a esas variables dependiendo de la implementación de la JVM (pero mucha menos penalización que una región de exclusión mutua). Ahí está, el double-checked locking por fin funcionando en Java:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;code&gt;&lt;br /&gt;// Works with acquire/release semantics for volatile&lt;br /&gt;// Broken under Java 1.4 and earlier semantics for volatile&lt;br /&gt;class Foo {&lt;br /&gt;&amp;nbsp;&amp;nbsp;private &lt;strong&gt;&lt;u&gt;volatile&lt;/u&gt;&lt;/strong&gt; Helper helper = null;&lt;br /&gt;&amp;nbsp;&amp;nbsp;public Helper getHelper() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (helper == null) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;synchronized(this) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (helper == null)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;helper = new Helper();&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;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return helper;&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;// other functions and members...&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/blockquote&gt;&lt;br /&gt;En estos tres artículos está perfectamente explicado así que no añadiré mucho más:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Double-checked_locking"&gt;http://en.wikipedia.org/wiki/Double-checked_locking&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://jeremymanson.blogspot.com/2008/05/double-checked-locking.html"&gt;http://jeremymanson.blogspot.com/2008/05/double-checked-locking.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html"&gt;http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;P.D: En este artículo se explica perfectamente el modificador &lt;code&gt;volatile&lt;/code&gt; y su comparación con &lt;code&gt;synchronized&lt;/code&gt;: &lt;a href="http://www.javaperformancetuning.com/news/qotm030.shtml"&gt;http://www.javaperformancetuning.com/news/qotm030.shtml&lt;/a&gt; &lt;blockquote&gt;&lt;em&gt;(...) &lt;code&gt;volatile&lt;/code&gt; only synchronizes the value of one variable between thread memory and "main" memory, while&lt;code&gt;synchronized&lt;/code&gt; synchronizes the value of all variables between thread memory and "main" memory, and locks and releases a monitor to boot. Clearly synchronized is likely to have more overhead than volatile.&lt;/em&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Y hago referencia a un nuevo artículo divulgativo de Jeremy Manson explicando muy mascadito qué implica el keyword &lt;code&gt;volatile&lt;/code&gt; en Java: &lt;a href="http://jeremymanson.blogspot.com/2008/11/what-volatile-means-in-java.html"&gt;http://jeremymanson.blogspot.com/2008/11/what-volatile-means-in-java.html&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-8787935917561327289?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/8787935917561327289/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=8787935917561327289' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/8787935917561327289'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/8787935917561327289'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/07/double-checked-locking-por-fin-funciona.html' title='&quot;Double checked locking&quot; por fin funciona en Java'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_4ZEuwiCuF6A/SFeNLcNUusI/AAAAAAAAADE/YCAAduI4sNA/s72-c/ico_lock_smiley.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-7018883641281257020</id><published>2008-06-29T23:45:00.001+02:00</published><updated>2008-12-10T12:55:15.221+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GC'/><category scheme='http://www.blogger.com/atom/ns#' term='JDK/JVM'/><category scheme='http://www.blogger.com/atom/ns#' term='Out-of-box'/><category scheme='http://www.blogger.com/atom/ns#' term='Memoria'/><title type='text'>Tamaño máximo de heap (y tamaño mínimo del heap)</title><content type='html'>&lt;a href="http://4.bp.blogspot.com/_4ZEuwiCuF6A/SFaAU48Q1RI/AAAAAAAAAC8/iktqVDiG6HI/s1600-h/fig4.gif"&gt;&lt;img id="BLOGGER_PHOTO_ID_5212494715098813714" style="FLOAT: right; MARGIN: 0px 0px 10px 10px" alt="" src="http://4.bp.blogspot.com/_4ZEuwiCuF6A/SFaAU48Q1RI/AAAAAAAAAC8/iktqVDiG6HI/s200/fig4.gif" border="0" /&gt;&lt;/a&gt;En otro artículo desgranaré algunos posibles argumentos / parámetros de lanzamiento de la máquina virtual. Pero una nota muy rápida para que quede claro, porque es una pregunta muy usada: &lt;strong&gt;¿cuál es el tamaño máximo de heap adecuado para establecer con -Xmx? &lt;/strong&gt;&lt;br /&gt;&lt;p&gt;Muy sencillo: la regla general es que &lt;span style="FONT-WEIGHT: bold"&gt;en un servidor donde se está ejecutando una máquina virtual JAMÁS debe agotarse la memoria física&lt;/span&gt;. Jamás debe llegar a utilizarse el swap a disco. Nunca. Never. Jamais. Nie. Mai. Nooit.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Esto significa que sumando los heaps máximos de todas las máquinas virtuales que pueden ejecutarse en un servidor, deberemos asignar como máximo entre 0,5 y 1,5 GBytes menos de tamaños máximos de heap (sumados) que la memoria física de que dispone nuestra máquina. Nota: esta regla es fruto de mi experiencia, quizás por ahí haya otras medidas... ummm... ¿qué tal un 80%-20% o un 90%-10%? :-)&lt;/p&gt;&lt;p&gt;Es decir, si tenemos 16 gigas, usar siempre como máximo 14,5-15,5, el resto debe ser sufiente para tareas de automantenimiento, backups, scripts de consulta o consolas o sorpresas.&lt;/p&gt;¿Por qué? Muy sencillo: el recolector de basura debe recorrer todo el heap, eso implica que si parte de éste está swapeado, el proceso de recolección generará un montón de fallos de página, lo que puede derivar en un auténtico desastre por OutOfMemoryError's muy frecuentes a poca carga que tengamos. Es decir, el modelo de GC no se lleva nada bien con un sistema de swapping a disco.&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Y por cierto, para evitar fragmentación del heap y redimensionamientos no deseados en entornos de producción el tamaño inicial (-Xms) debe igualarse al máximo (-Xmx).&lt;/span&gt; Las pruebas demuestran que esto último tiene más importancia en la máquina virtual de Bea que en la de Sun.&lt;br /&gt;&lt;br /&gt;También hay otras consideraciones a tener en cuenta, como el establecimiento de -Xmn para el tamaño de la zona de young generation (zona "Eden" + survivors), así como las políticas de promoción entre zonas y recolección de basura. Pero eso será objeto de ese artículo y no suele ser necesario si ayudamos a la JVM con -server/-client.&lt;br /&gt;&lt;br /&gt;&lt;p&gt;P.D: Aunque no es mi caso actualmente, además, tengamos en cuenta que cuanto mayor sea el heap, más le costará al GC hacer su trabajo, por lo que debemos tener cuidado con heaps de más de 50 gigas por mucho maquinón que nos pongan. Tenía por ahí alúna otra referencia que ahora no encuentro, dejo un link a &lt;a href="http://dev2dev.bea.com/blog/hstahl/archive/2007/03/the_biggest_jvm.html"&gt;http://dev2dev.bea.com/blog/hstahl/archive/2007/03/the_biggest_jvm.html&lt;/a&gt; ¿3,5 TBytes de heap? Guau!!!!.&lt;/p&gt;&lt;p&gt;Lo cierto, como aparece en un comentario que leí por ahí, es que si necesitamos semejante heap es que tenemos un problema de diseño de cojones en nuestra aplicación...&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-7018883641281257020?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/7018883641281257020/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=7018883641281257020' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/7018883641281257020'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/7018883641281257020'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/06/tamao-mximo-de-heap-y-tamao-mnimo-del.html' title='Tamaño máximo de heap (y tamaño mínimo del heap)'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_4ZEuwiCuF6A/SFaAU48Q1RI/AAAAAAAAAC8/iktqVDiG6HI/s72-c/fig4.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-4399213399698440332</id><published>2008-06-23T23:43:00.003+02:00</published><updated>2008-12-10T12:55:15.410+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JDK/JVM'/><category scheme='http://www.blogger.com/atom/ns#' term='Out-of-box'/><title type='text'>Out-of-Box Performance ("Out of the box")</title><content type='html'>&lt;a href="http://4.bp.blogspot.com/_4ZEuwiCuF6A/SE6Iwrbxy4I/AAAAAAAAACc/dxfE9-gRe2Y/s1600-h/out-of-box.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5210252188788575106" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://4.bp.blogspot.com/_4ZEuwiCuF6A/SE6Iwrbxy4I/AAAAAAAAACc/dxfE9-gRe2Y/s1600/out-of-box.jpg" border="0" /&gt;&lt;/a&gt; &lt;p&gt;Se trata, para mi, de uno de los asuntos más importantes en el mundo de las máquinas virtuales: que el rendimiento y escalabilidad de una plataforma Java "sin tunear" (o auto-tuneada) sea muy parecida a lo que podríamos conseguir tuneándolo específicamente para un tipo de sistema o para un benchmark concreto.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Y digo que es importantísimo por tres motivos:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;No siempre tenemos el tiempo adecuado para tunear todos los sistemas en cualquier circunstancia, o no siempre tenemos el equipo de ingeniero de sistemas adecuado, o no siempre tienen el tiempo o disponibilidad necesaria para hacer esas labores de tuning fino.&lt;/li&gt;&lt;li&gt;Las posibilidades de parametrización en el arranque de la máquina virtual son casi infinitas, un infierno me atrevería a decir, y las probabilidades de empeorar alguno de los aspectos de una aplicación cuando mejoramos perceptiblemente otros son muy altas, en mi experiencia, y no siempre son inmediatas de cazar.&lt;/li&gt;&lt;li&gt;El mundo no es inmóvil ni inmutable, y las condiciones en que se ejecuta un sistema van evolucionando (en concurrencia, carga, usuarios, tamaños de ficheros intercambiados, sistemas con los que se integra, nuevos elementos de red, etc), por lo que con el tiempo pueden dejar de tener sentido decisiones iniciales. Este problema es serio: me he encontrado con situaciones en las que había opciones de lanzamiento "heredadas" o no cambiadas en 3 años y al cambiar de versión de JVM ha sido contraproducente y una penalización en escalabilidad respecto a no haber puesto casi nada.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;En este aspecto, las implementaciones modernas tanto de Hotspot como de JRockit tienen mejoras sustanciales. Fue muy sonado el anuncio de Sun en cuanto al Out-of-box performance del Java SE 6, aunque Bea asegura que su equivalente tiene incluso mejores prestaciones "Out-of-box".&lt;/p&gt;&lt;p&gt;¿Qué significa esto? Que con especificar parámetros en cuanto a tamaños de heap y poco más (ayudando con "-server"/"-client" pero en JRockit ni eso, al igual que Hotspot en algunos S.O.), hoy en día es casi suficiente para el 80% de las necesidades de nuestras aplicaciones y servicios. En algunos benchmarks que yo he hecho en mis aplicaciones, contrastándolo con una configuración "supertuneada" específicamente, la diferencia es sólo de entre un 0% y un 10% tanto en rendimiento como en escalabilidad. Mola.&lt;/p&gt;&lt;p&gt;Y lo que digo para Java SE se aplica en casi todos los órdenes de esta vida tecnológica: sistemas operativos, BIOS, etc.&lt;/p&gt;&lt;p&gt;Unas pocas referencias:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://blogs.sun.com/dagastine/entry/java_se_out_of_box1"&gt;http://blogs.sun.com/dagastine/entry/java_se_out_of_box1&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.javalobby.org/java/forums/t86031.html"&gt;http://www.javalobby.org/java/forums/t86031.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://dev2dev.bea.com/blog/hstahl/archive/2007/08/a_second_look_a.html"&gt;http://dev2dev.bea.com/blog/hstahl/archive/2007/08/a_second_look_a.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.webservices.org/categories/development/java/bea_jrockit_for_java_se_6_now_available"&gt;http://www.webservices.org/categories/development/java/bea_jrockit_for_java_se_6_now_available&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.linuxtoday.com/infrastructure/2007050200626OPSW"&gt;http://www.linuxtoday.com/infrastructure/2007050200626OPSW&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-4399213399698440332?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/4399213399698440332/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=4399213399698440332' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/4399213399698440332'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/4399213399698440332'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/06/out-of-box-performance-out-of-box.html' title='Out-of-Box Performance (&quot;Out of the box&quot;)'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_4ZEuwiCuF6A/SE6Iwrbxy4I/AAAAAAAAACc/dxfE9-gRe2Y/s72-c/out-of-box.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-5387555754302849891</id><published>2008-06-20T16:12:00.009+02:00</published><updated>2008-12-10T12:55:15.561+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Strings/Buffers/Ficheros'/><category scheme='http://www.blogger.com/atom/ns#' term='GC'/><category scheme='http://www.blogger.com/atom/ns#' term='Memoria'/><title type='text'>Buffers: por defecto y por exceso</title><content type='html'>Llevo 11 años en el mundo Java. A lo largo de ese tiempo ven viniendo como los maderos a la playa los mismos error repetidos en quizás 20 ocasiones por personas distintas, en momentos distintos.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;Defecto&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Por ejemplo este: cargar todo el contenido de un fichero o un blob en memoria, no para trabajar con sus datos (que sería hasta discutible) sino para derivarlo hacia otra colaboración/proceso/cliente.&lt;br /&gt;&lt;br /&gt;Hace poco me he encontrado, de nuevo, con un código similar a este para enviarle un fichero al navegador (eliminadas las partes de content-disposition, content-type, excepciones, etc):&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-family:courier new;"&gt;&lt;code&gt;&lt;br /&gt;input = new java.io.FileInputStream(pdf);&lt;br /&gt;int longitud = input.available();&lt;br /&gt;byte [] datos = &lt;strong&gt;new byte [longitud];&lt;/strong&gt;&lt;br /&gt;input.read(datos);&lt;br /&gt;response.getOutputStream().write(datos);&lt;br /&gt;response.getOutputStream().flush();&lt;/code&gt;&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;Lo que podríamos catalogar de como mínimo "bestia" si no sabemos si puede tratarse de ficheros pequeños o grandes, o si vamos a tener un poquito de concurrencia. ¡Aparte de que vaya usted a saber qué valor devuelve el método &lt;code&gt;available()&lt;/code&gt;!&lt;br /&gt;&lt;br /&gt;Es cierto que cada vez la memoria es más "barata" y que tiende a pensarse que es infinita... pero también es cierto que el número de sesiones simultáneas, clientes concurrentes y tamaño de los ficheros / contenidos multimedia crece en una proporción similar. &lt;strong&gt;¿Tanto cuesta utilizar un pequeño buffer?&lt;/strong&gt;. Un código equivalente similar a este:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-family:courier new;"&gt;&lt;code&gt;input = new java.io.FileInputStream(pdf);&lt;br /&gt;byte [] buffer = &lt;strong&gt;new byte [16*1024];&lt;/strong&gt; // 16 KBytes&lt;br /&gt;OutputStream output = response.getOutputStream();&lt;br /&gt;int readed;&lt;br /&gt;while ( (readed = input.read(buffer)) &gt; 0 ) {&lt;br /&gt;  output.write(buffer, 0, readed);&lt;br /&gt;}&lt;br /&gt;out.flush();&lt;/code&gt;&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;strong&gt;Importantísimo:&lt;/strong&gt; Sólo hay que escribir el tamaño real que el método de lectura ha metido en el buffer, lo que significaría que en la última escritura a la salida meteríamos basura detrás del final de lo que realmente teníamos que escribir, y eso puede dar problemas serios. Es decir me suelo encontrar con esta otra versión del bucle que es &lt;strong&gt;ABSOLUTAMENTE INCORRECTA&lt;/strong&gt; (yo mismo la he cagao en alguna ocasión reciente, al loro): &lt;blockquote&gt;&lt;span style="font-family:courier new;"&gt;&lt;code&gt;while ( (fiPdf.read(buffer)) &gt; 0 ) {&lt;br /&gt;  out.write(buffer);&lt;br /&gt;}&lt;/code&gt;&lt;/span&gt;&lt;/blockquote&gt;Por cierto, en mi experiencia, en función de la arquitectura y sistema operativo, tamaños de entre 16 y 32 KBytes suelen ser los apropiados para este tipo de operaciones y para el uso de &lt;code&gt;java.io.BufferedInputStream&lt;/code&gt; y &lt;code&gt;java.io.BufferedOutputStream&lt;/code&gt; (por cierto esas clases usan por defecto un buffer 8KBytes si no especificas otra cosa en sus contructores).&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;Exceso&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Por otro lado, también es común encontrarnos con el caso contrario: &lt;strong&gt;utilizar buffers cuando no hacen falta.&lt;/strong&gt; ¿Cuántas veces hemos visto algo parecido a &lt;code&gt;new GZIPOutputStream(new BufferedInputStream(new FileOutputStream(tempFile)))&lt;/code&gt;? ¿o &lt;code&gt;ps.setBlob(1, new BufferedInputStream(new FileInputStream(tempFile),32*1024), tempFile.length())&lt;/code&gt;. Y el desarrollador, tan orgulloso de ser más listo que nadie.&lt;br /&gt;&lt;br /&gt;Por regla general, si vamos a invocar a un método cuyo parámetro es un InputStream o un OutputStream, no hay que utilizar como intermediario un buffer porque &lt;strong&gt;por regla general&lt;/strong&gt; el método invocado está optimizado. Es decir, debemos confiar en nuestros partners. Y por supuesto, si partimos de un array, no usemos un buffer como intermediario, ¡porque nuestro origen ya es un buffer!&lt;br /&gt;&lt;br /&gt;En definitiva, tanto por exceso como por defecto, nos podemos encontrar con un sobre uso de la memoria con un efecto multiplicador más que curioso.&lt;br /&gt;&lt;br /&gt;Muchas veces le doy vueltas a que deberían darle alguna que otra pensada a la implementación interna de los arrays en la máquina virtual; es decir que internamente la JVM hiciera swapping a disco de arrays grandes como uno de los pasos del recolector de basura, GC!!!&lt;br /&gt;&lt;br /&gt;Hablando del tema... en su día yo hice una clase que era una especie de abstracción de todo esto: un "ByteArrayAdapter" que internamente decidía utilizar un byte array o un fichero temporal en función de tamaños y algunos que otros condicionantes, de forma transparente al desarrollador. El problema es el de siempre: difícil de explicar y difícil de recordar que existe si no eres el creador de la criatura, y una cosa más que mantener. Repito el autoconsejo de uno de los primeros posts: cuanto menos contenido tenga la biblioteca propia de clases de nuestra compañía / grupo de trabajo / producto, mucho mejor. (¿Por qué todos nos empeñamos en que tenemos que tener una biblioteca estándar en nuestra empresa? ¿por qué tenemos que creernos más listos que las comunidades opensource? ¿por qué terminamos teniendo cuatro versiones de lo mismo que encima los nuevos integrantes de los equipos terminan "olvidando"? Si siempre pasa lo mismo, no caigamos en lo mismo de siempre.&lt;br /&gt;&lt;br /&gt;Bueno, que me he ido del asunto. Volvemos a lo de siempre: &lt;strong&gt;seguimos necesitando que el desarrollador sea un ser pensante y con experiencia&lt;/strong&gt;. Afortunadamente, por cierto.&lt;br /&gt;&lt;br /&gt;Nota: el tema de este post en realidad es la escalabilidad más que el rendimiento :-)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_4ZEuwiCuF6A/SEbT16Nv0vI/AAAAAAAAABU/PaENLVMkRKw/s1600-h/kingston_ddr3_11000ul.gif"&gt;&lt;img id="BLOGGER_PHOTO_ID_5208082942214001394" style="DISPLAY: block; MARGIN: 0px auto 10px; TEXT-ALIGN: center" alt="" src="http://3.bp.blogspot.com/_4ZEuwiCuF6A/SEbT16Nv0vI/AAAAAAAAABU/PaENLVMkRKw/s400/kingston_ddr3_11000ul.gif" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-5387555754302849891?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/5387555754302849891/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=5387555754302849891' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/5387555754302849891'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/5387555754302849891'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/06/buffers-por-defecto-y-por-exceso.html' title='Buffers: por defecto y por exceso'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_4ZEuwiCuF6A/SEbT16Nv0vI/AAAAAAAAABU/PaENLVMkRKw/s72-c/kingston_ddr3_11000ul.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-7072230457512307199</id><published>2008-06-17T14:34:00.005+02:00</published><updated>2008-11-21T10:27:01.305+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java CAPS'/><title type='text'>Java CAPS y Open ESB: Enlaces de interés y recursos</title><content type='html'>Una recopilación no exhaustiva de referencias sobre &lt;strong&gt;Java CAPS&lt;/strong&gt; y en menor medida sobre &lt;strong&gt;Open ESB&lt;/strong&gt;, y no sólo de temas relacionados con rendimiento o escalabilidad. Iré actualizándola...&lt;br /&gt;&lt;br /&gt;&lt;em&gt;[Actualizado el 25/8/2008: añadidos algunos enlaces de interés tomados del blog &lt;/em&gt;&lt;a href="http://camelcase.blogspot.com/"&gt;&lt;em&gt;CamelCase&lt;/em&gt;&lt;/a&gt;&lt;em&gt;, como la nueva wiki]&lt;br /&gt;&lt;/em&gt;&lt;br /&gt;&lt;strong&gt;Soporte y Documentación oficial de Sun:&lt;/strong&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.sun.com/software/javaenterprisesystem/javacaps/index.jsp"&gt;www.sun.com/software/javaenterprisesystem/javacaps/index.jsp&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://docs.sun.com/app/docs/prod/sj.caps~1604.2#hic"&gt;http://docs.sun.com/app/docs/prod/sj.caps~1604.2#hic&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://developers.sun.com/docs/javacaps/index.jsp"&gt;http://developers.sun.com/docs/javacaps/index.jsp&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://open-esb.dev.java.net/"&gt;https://open-esb.dev.java.net/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://goldstar.seebeyond.com/support/default.asp"&gt;http://goldstar.seebeyond.com/support/default.asp&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;strong&gt;Foros:&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://forum.java.sun.com/forum.jspa?forumID=882"&gt;http://forum.java.sun.com/forum.jspa?forumID=882&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://eai.ittoolbox.com/groups/technical-functional/seebeyond-l"&gt;http://eai.ittoolbox.com/groups/technical-functional/seebeyond-l&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;strong&gt;Wikis:&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://wikis.sun.com/display/JavaCAPS/Home"&gt;http://wikis.sun.com/display/JavaCAPS/Home&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://wikis.sun.com/display/JavaCAPS/Sun+Java+CAPS+5.1.3"&gt;http://wikis.sun.com/display/JavaCAPS/Sun+Java+CAPS+5.1.3&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://wikis.sun.com/display/JavaCAPS/Sun+Java+CAPS+5.1.2"&gt;http://wikis.sun.com/display/JavaCAPS/Sun+Java+CAPS+5.1.2&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;strong&gt;Herramientas y otros:&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="https://jcaps-repository-tools.dev.java.net/"&gt;https://jcaps-repository-tools.dev.java.net/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://jcaps-b2b.dev.java.net/"&gt;https://jcaps-b2b.dev.java.net/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://jcaps-rfid.dev.java.net/"&gt;https://jcaps-rfid.dev.java.net/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://jmsjca.dev.java.net/"&gt;https://jmsjca.dev.java.net/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://caps-solutions.dev.java.net/"&gt;https://caps-solutions.dev.java.net/&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;strong&gt;Libros:&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/Java-CAPS-Basics-Implementing-Patterns/dp/0137130716"&gt;http://www.amazon.com/Java-CAPS-Basics-Implementing-Patterns/dp/0137130716&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;strong&gt;Videos:&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=MutW-_G7odc"&gt;http://www.youtube.com/watch?v=MutW-_G7odc&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://mediacast.sun.com/share/hb199203/Webinar-11_Expose-JCD-As-WS.wmv"&gt;http://mediacast.sun.com/share/hb199203/Webinar-11_Expose-JCD-As-WS.wmv&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=m59wA5FhjiQ"&gt;http://www.youtube.com/watch?v=m59wA5FhjiQ&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=ZqU8k3RjHxE"&gt;http://www.youtube.com/watch?v=ZqU8k3RjHxE&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=IT6Hbo81xDs"&gt;http://www.youtube.com/watch?v=IT6Hbo81xDs&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;strong&gt;Blogs:&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://blogs.sun.com/javacapsfieldtech/"&gt;http://blogs.sun.com/javacapsfieldtech/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blogs.sun.com/jcapsuser/"&gt;http://blogs.sun.com/jcapsuser/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://jcapsblogger.blogspot.com/"&gt;http://jcapsblogger.blogspot.com/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blogs.sun.com/shoshin/"&gt;http://blogs.sun.com/shoshin/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blogs.sun.com/rupesh/"&gt;http://blogs.sun.com/rupesh/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blogs.sun.com/adamt/"&gt;http://blogs.sun.com/adamt/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blogs.sun.com/kevinschmidt/"&gt;http://blogs.sun.com/kevinschmidt/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blogs.sun.com/gopalan/"&gt;http://blogs.sun.com/gopalan/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blogs.sun.com/fkieviet/"&gt;http://blogs.sun.com/fkieviet/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://camelcase.blogspot.com/"&gt;http://camelcase.blogspot.com/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blogs.sun.com/lerognon/"&gt;http://blogs.sun.com/lerognon/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blogs.sun.com/cye/"&gt;http://blogs.sun.com/cye/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blogs.sun.com/fredaabedi/"&gt;http://blogs.sun.com/fredaabedi/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blogs.sun.com/shelby/"&gt;http://blogs.sun.com/shelby/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blogs.sun.com/catalysts/"&gt;http://blogs.sun.com/catalysts/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blogs.sun.com/jason/"&gt;http://blogs.sun.com/jason/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blogs.sun.com/polyblog/"&gt;http://blogs.sun.com/polyblog/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://rabisblog.blogspot.com/"&gt;http://rabisblog.blogspot.com/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://vincentfazio.blogspot.com/"&gt;http://vincentfazio.blogspot.com/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blogs.sun.com/openmessagequeue/"&gt;http://blogs.sun.com/openmessagequeue/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://soa4real.blogspot.com/"&gt;http://soa4real.blogspot.com/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blogs.sun.com/toxophily/"&gt;http://blogs.sun.com/toxophily/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://planets.sun.com/SOABI/group/blogs/"&gt;http://planets.sun.com/SOABI/group/blogs/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://serverperformance.blogspot.com/"&gt;http://serverperformance.blogspot.com/&lt;/a&gt; :-)&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;strong&gt;del.icio.us&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://del.icio.us/tag/javacaps"&gt;http://del.icio.us/tag/javacaps&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://del.icio.us/tag/jcaps"&gt;http://del.icio.us/tag/jcaps&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://del.icio.us/tag/seebeyond"&gt;http://del.icio.us/tag/seebeyond&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://del.icio.us/tag/suncaps"&gt;http://del.icio.us/tag/suncaps&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://del.icio.us/tag/openesb"&gt;http://del.icio.us/tag/openesb&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;Technorati&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://technorati.com/tag/Java+CAPS"&gt;http://technorati.com/tag/Java+CAPS&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://technorati.com/tag/JCAPS"&gt;http://technorati.com/tag/JCAPS&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;Twitter&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://tweetscan.com/rss.php?s=java+caps"&gt;http://tweetscan.com/rss.php?s=java+caps&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://tweetscan.com/rss.php?s=jcaps"&gt;http://tweetscan.com/rss.php?s=jcaps&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;Facebook&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.facebook.com/group.php?gid=17757823536"&gt;http://www.facebook.com/group.php?gid=17757823536&lt;/a&gt; &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Nota: Muchas de estas referencias son recopilación mías, pero otras muchas están copiadas de la gran recopilación hecha por Sebastian Krueger (&lt;/em&gt;&lt;a href="http://jcapsblogger.blogspot.com/2008/04/some-tips-on-following-java-caps-news.html"&gt;&lt;em&gt;http://jcapsblogger.blogspot.com/2008/04/some-tips-on-following-java-caps-news.html&lt;/em&gt;&lt;/a&gt;&lt;em&gt;) y he tomado otras del blog &lt;/em&gt;&lt;a href="http://camelcase.blogspot.com/"&gt;&lt;em&gt;CamelCase&lt;/em&gt;&lt;/a&gt;&lt;em&gt; referenciado arriba).&lt;/em&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-7072230457512307199?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/7072230457512307199/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=7072230457512307199' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/7072230457512307199'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/7072230457512307199'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/06/java-caps-y-open-esb-enlaces-de-inters.html' title='Java CAPS y Open ESB: Enlaces de interés y recursos'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-6846247740759600877</id><published>2008-06-14T16:10:00.009+02:00</published><updated>2008-12-10T12:55:15.794+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GC'/><category scheme='http://www.blogger.com/atom/ns#' term='JDK/JVM'/><title type='text'>Sun Hotspot -vs- Bea JRockit</title><content type='html'>&lt;a href="http://2.bp.blogspot.com/_4ZEuwiCuF6A/SE5r7B_dmRI/AAAAAAAAACM/RTGa__ZA_as/s1600-h/Java6-OOB-1.jpg"&gt;&lt;img style="FLOAT: right; MARGIN: 0px 0px 10px 10px; CURSOR: hand" alt="" src="http://2.bp.blogspot.com/_4ZEuwiCuF6A/SE5r7B_dmRI/AAAAAAAAACM/RTGa__ZA_as/s200/Java6-OOB-1.jpg" border="0" /&gt;&lt;/a&gt; &lt;p&gt;&lt;em&gt;Actualización 19/9/2008: Nuevo blog corporativo de Henrik, ahora que les ha comprado Oracle...&lt;/em&gt;&lt;/p&gt;&lt;p&gt;Dejo enlaces a los weblogs de miembros de los equipos de rendimiento de Sun y de Bea (ahora Oracle), para sus respectivas máquinas virtuales, Hotspot y JRockit. Algunos artículos son más que interesantes:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://blogs.sun.com/dagastine/"&gt;http://blogs.sun.com/dagastine/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;strike&gt;&lt;a href="http://dev2dev.bea.com/blog/hstahl/"&gt;http://dev2dev.bea.com/blog/hstahl/&lt;/a&gt;&lt;/strike&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blogs.oracle.com/jrockit/"&gt;http://blogs.oracle.com/jrockit/&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Je, je, es la gran batalla que da "vidilla" al rendimiento y escalabilidad en Java sobre plantaformas x86 y x64. Una vez más se demuestra que la competencia fomenta la innovación y el avance (vaya, esto parece un alegato capitalista antimonopolio :-) Bueno, están IBM y HP por ahí también, sobre todo IBM tuvo ganada la partida en el mundo Intel en los tiempos del JDK 1.1 y 1.2... pero para mi hoy en día son convidados de piedra en este juego, especializados en sus arquitecturas respectivas.&lt;/p&gt;&lt;p&gt;¿Y tú de quién eres? No, no, no se puede ser agnóstico, hay que tomar partido. Esto es como las decisiones Rolling/Beatles, Intel/AMD, Barça/Madrid, Windows/Linux, Cocacola/Pepsi, Fanta/Kas, MortadeloFilemón/ZipiZape, Astérix/Tintín, Demócratas/Republicanos, Google/Yahoo, Java/C++, Redhat/SuSE. Hay que tomar partido. Y defender tu posición. :-)&lt;/p&gt;&lt;p&gt;Si tengo que ser sincero, le tengo especial cariño a JRockit por aquello de que me sacó de un gran apuro hace ya tiempo en un proyecto, sólo con cambiar de máquina virtual y tunear algunas cosillas... aquello fue como magia. Pero eran los tiempos en que acababa de salir el JDK 1.4.2 y ha llovido mucho desde entonces. &lt;p&gt;&lt;p&gt;Y como cada uno cacarea los resultados que quiere en sus publicidades, y mi sensación es que a día de hoy ambas tecnologías son muy parejas, mi opinión es que hoy en día hay que ser pragmático: si vas a ejecutar un Weblogic / Aqualogic, móntalo sobre JRockit; y si vas a ejecutar un Glassfish / JES / Java CAPS, hazlo sobre la JVM de Sun.&lt;/p&gt;&lt;p&gt;Porque suelen venir ya "pretuneados", o al menos han sido muy probadas esas combinaciones, y porque no quiero tener problemas cuando reporto una incidencia a los equipos de soporte de Sun y de Bea respectivamente. Porque su primera respuesta es obvia ante un reporte de incidencia, esto es como cuando vas al médico por lo que sea: ya sabes que lo primero de todo te va a decir que dejes de fumar y que adelgaces. Aunque tengas una rotura de fibras.&lt;/p&gt;&lt;p&gt;Es decir, reconozco que hoy en día estoy utilizando Sun Java SE 6.0 sobre Linux x64. Pero algún día jugaremos un poco a ver qué pasa...&lt;/p&gt;&lt;p&gt;P.D: Por cierto, he mantenido una conversación por email muy interesante con Henrik Ståhl. Y he de reconocer que estoy gratamente sorprendido no sólo por su capacidad profesional (que se le presupone) sino por su amabilidad e interés acerca de mis necesidades / caso de uso.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-6846247740759600877?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/6846247740759600877/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=6846247740759600877' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/6846247740759600877'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/6846247740759600877'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/06/sun-hotspot-vs-bea-jrockit.html' title='Sun Hotspot -vs- Bea JRockit'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SE5r7B_dmRI/AAAAAAAAACM/RTGa__ZA_as/s72-c/Java6-OOB-1.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-1747589861179879866</id><published>2008-06-14T16:08:00.003+02:00</published><updated>2008-12-10T12:55:15.914+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='General'/><title type='text'>Disclaimers (II)</title><content type='html'>&lt;img id="BLOGGER_PHOTO_ID_5207976560169046626" style="FLOAT: left; MARGIN: 0px 10px 10px 0px; CURSOR: hand" alt="" src="http://2.bp.blogspot.com/_4ZEuwiCuF6A/SEZzFqNv0mI/AAAAAAAAAAM/qOqa3EKs7Ns/s320/disclaimer.gif" border="0" /&gt; &lt;p&gt;Otra cosilla, aparte de otros &lt;a href="http://serverperformance.blogspot.com/search/label/Disclaimers"&gt;disclaimers generales&lt;/a&gt; (por cierto, literalmente Disclaimer significa "Negación").&lt;/p&gt;&lt;p&gt;Lo que aquí voy dejando para la posteridad no tiene por qué ser la Verdad absoluta, incluso puede que esté muy equivocado en más de una aserción. Son mis opiniones y/o experiencias en unos entornos, aplicaciones y momentos concretos que pueden diferir de lo que algún googler eventualmente vaya buscando si termina parando en esta esquinita de la web.&lt;/p&gt;&lt;p&gt;Es curioso porque el ser humano tiende a poner en tela de juicio constantemente versiones oficiales, leyes, libros, dogmas de fe, teorías científicas, lo que nos dicen los consultores de las grades empresas, etc, pero por el motivo que sea tendemos a creer que lo que encontramos googleando o en la wikipedia es la verdad absoluta. Que el anonimato obliga. Por algo se habrá escrito. El autor no gana nada con mentir deliveradamente.&lt;/p&gt;&lt;p&gt;Pero la realidad no tiene por qué ser esa, y no por mala fe. En el 70% de los casos la gente escribe de oídas o porque lo ha leído en otro foro o blog, y en raras ocasiones alguien se ha molestado en hacer una prueba de carga en condiciones y de perfilar una ejecución. En cualquier caso siempre estamos influidos por los prejuicios, o por lo que nos infundió gente a la que respetamos, o de empresas/apuestas a las que tenemos má cariño que a otras.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Así que aviso para navegantes, estas son mis opiniones, esta es mi verdad, que puede cambiar con el tiempo :-)&lt;/strong&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-1747589861179879866?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/1747589861179879866/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=1747589861179879866' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/1747589861179879866'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/1747589861179879866'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/06/disclaimers-ii.html' title='Disclaimers (II)'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SEZzFqNv0mI/AAAAAAAAAAM/qOqa3EKs7Ns/s72-c/disclaimer.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-6466628727363024436</id><published>2008-06-11T23:58:00.015+02:00</published><updated>2008-12-10T12:55:16.205+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JDK/JVM'/><title type='text'>Java SE 6u5p Performance Release</title><content type='html'>&lt;p style="FONT-STYLE: italic"&gt;[Nota de octubre'08 ==&gt;&lt;/p&gt;&lt;p style="FONT-STYLE: italic"&gt;Querido googler: si llegas a esta página -como muchos- buscando información de las performance releases del JRE 6, quizás te interesen los artículos posteriores &lt;a href="http://serverperformance.blogspot.com/2008/07/java-se-6u6p-performance-release.html"&gt;Java SE 6u6p Performance Release&lt;/a&gt;,&lt;br /&gt;&lt;a href="http://serverperformance.blogspot.com/2008/08/java-se-6u6-p-performance-release-ya.html"&gt;Java SE 6u6-p Performance Release - YA DISPONIBLE EN OTRAS PLATAFORMAS&lt;/a&gt; y &lt;a href="http://serverperformance.blogspot.com/2008/09/6u6-p-pues-en-linux-x64-peta.html"&gt;6u6-p: Pues en Linux x64 peta!!!!!!!&lt;/a&gt;]&lt;/p&gt;&lt;p&gt;Aunque la noticia tiene más de un mes, yo lo acabo de descubrir: Sun lanza una versión especial de Java SE 6 (llamada 6u5p) incluyendo las últimas innovaciones en rendimiento que eventualmente se incorporarán a futuras versiones de la plataforma.&lt;/p&gt;&lt;p&gt;Copia literal de la web de Sun:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;em&gt;May 2008&lt;/em&gt;&lt;br /&gt;&lt;a href="http://java.sun.com/javase/performance/survey.html"&gt;&lt;em&gt;&lt;strong&gt;Java SE 6u5p Performance Release&lt;/strong&gt;&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;This special version of Java SE includes the very latest performance innovations from Sun on selected platforms. The software is free for download, application performance testing, and benchmark submissions. Performance releases may be used in production. If desired, support is available via a Sun Java support contract. These performance enhancements will be included in an upcoming standard release of the Java SE platform. Please &lt;/em&gt;&lt;a href="http://java.sun.com/javase/performance/feedback.jsp"&gt;&lt;em&gt;share with us&lt;/em&gt;&lt;/a&gt;&lt;em&gt; your experience using this special advance release.&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Y veo este mini resumen en estas trasparencias de Java One - &lt;a href="http://blogs.sun.com/dannycoward/resource/PS_TS-6271_SETrackTalk_Final.pdf"&gt;http://blogs.sun.com/dannycoward/resource/PS_TS-6271_SETrackTalk_Final.pdf&lt;/a&gt;:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;em&gt;&lt;strong&gt;Java SE 6u5p “Performance Release”&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;em&gt;Performance tuned release of the JRE™64bit architectures only&lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;Solaris, Windows, Linux&lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;Large number of small optimizations&lt;/em&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;&lt;em&gt;Crypto libraries, TreeMap, HashMap, XML Parsing&lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;Escape analysis, depth-first copying, page sizes&lt;/em&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;em&gt;Optimizations seep into future JRE updates&lt;/em&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;&lt;p&gt;Un poco exagerada la promesa de mejora que se ve en el gráfico de abajo ¿no?&lt;/p&gt;&lt;p&gt;&lt;a href="http://4.bp.blogspot.com/_4ZEuwiCuF6A/SE5znMmvXaI/AAAAAAAAACU/v0VnVQ-Sitg/s1600-h/6u5p.png"&gt;&lt;img id="BLOGGER_PHOTO_ID_5210228936150048162" style="DISPLAY: block; MARGIN: 10px auto; TEXT-ALIGN: center" alt="" src="http://4.bp.blogspot.com/_4ZEuwiCuF6A/SE5znMmvXaI/AAAAAAAAACU/v0VnVQ-Sitg/s1600/6u5p.png" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Sun no está dando mucha información de qué incorpora (o yo no lo he encontrado), pero la gráfica de arriba es prometedora, y parte de la información de mejoras también... ¿eso de optimizar TreeMap, HashMap y XML Parsing no recuerda sospechosamente a algunas de las técnicas utilizadas en la biblioteca de Javolution? (ver &lt;a href="http://serverperformance.blogspot.com/2008/06/javolution.html"&gt;http://serverperformance.blogspot.com/2008/06/javolution.html&lt;/a&gt;).&lt;/p&gt;&lt;p&gt;Pero siempre que ocurre alguna promesa de "milagro" de estos en lo que a rendimiento se refiere me surgen siempre dos dudas: ¿cuánto hay de cierto? y, lo que me come por dentro... ¿es que ahora somos muy listos o es que hasta hace 6 meses éramos todos muy tontos?&lt;/p&gt;&lt;p&gt;Puede solicitarse su descarga desde &lt;a href="http://java.sun.com/performance"&gt;&lt;strong&gt;http://java.sun.com/performance&lt;/strong&gt;&lt;/a&gt;, donde por cierto hay también unos cuantos documentos y recursos sobre rendimiento, escalabilidad y tunning.&lt;/p&gt;&lt;p&gt;Buena noticia esta "iniciativa 2.0". Creo que es la primera versión de anticipos de rendimiento que liberan así, como se ve en alguna gráfica de temporalidad de versiones, pero seguro que no es la última... habrá que ir chequeándolo...&lt;/p&gt;&lt;p&gt;En general me gusta la política de semi-puertas abiertas que tanto Sun con Bea/Oracle están siguiendo...&lt;/p&gt;&lt;p&gt;P.D: Ojo con utilizar esta versión en producción sin probarla muy-muy bien, veo en algunos foros y bug parade que ciertas opciones de GC fallan o que en algún caso muy concreto se comporta distinto que su hermana la versión estándar... &lt;strong&gt;Como siempre, es mejor seguir la máxima &lt;em&gt;"que prueben otros" &lt;/em&gt;salvo necesidades muy bien justificadas o actualizaciones menores de software&lt;/strong&gt; (esta no lo es aunque lo parezca), aunque la cabra tira al monte y el cuerpo nos pide marcha...&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-6466628727363024436?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/6466628727363024436/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=6466628727363024436' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/6466628727363024436'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/6466628727363024436'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/06/java-se-6u5p-performance-release.html' title='Java SE 6u5p Performance Release'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_4ZEuwiCuF6A/SE5znMmvXaI/AAAAAAAAACU/v0VnVQ-Sitg/s72-c/6u5p.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-3765029279659197042</id><published>2008-06-09T22:34:00.023+02:00</published><updated>2008-12-10T12:55:16.370+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='XML/SOAP'/><title type='text'>Rendimiento en transformaciones XSLT</title><content type='html'>&lt;p&gt;Esta vez voy a referenciar una serie de tres grandiosos posts hechos en el blog &lt;strong&gt;"Algo nuevo que hacer..."&lt;/strong&gt; (&lt;a href="http://www.cmaj.es/"&gt;http://www.cmaj.es/&lt;/a&gt;). Se trata de un blog muy interesante salpimentado con una pizca de tecnología y dos pizcas de liderazgo de equipos de trabajo y motivación.&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;XSLT en Java: uso de Translets&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Si estás -como yo- preocupado por el rendimiento y escalabilidad de las transformaciones XSLT en Java, ya habrás llegado a la conclusión de que la única forma de que el rendimiento y escalabilidad del cruce de un XML con su plantilla XSL sea decente es el uso de "translets", esto es clases precompiladas:&lt;/p&gt;&lt;a href="http://1.bp.blogspot.com/_4ZEuwiCuF6A/SE4_-vRqwCI/AAAAAAAAACE/vjZOqL3cELg/s1600-h/runtime_design.gif"&gt;&lt;img id="BLOGGER_PHOTO_ID_5210172165989253154" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://1.bp.blogspot.com/_4ZEuwiCuF6A/SE4_-vRqwCI/AAAAAAAAACE/vjZOqL3cELg/s1600/runtime_design.gif" border="0" /&gt;&lt;/a&gt; &lt;p&gt;No obstante, sigue este gran artículo dividido en tres entregas, muy interesante por la evolución cronológica que marca y por las sorpresas y tunnings realizados:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;em&gt;"Transformaciones XSL (I): Rápidas como el rayo"&lt;/em&gt;. &lt;a href="http://www.cmaj.es/2007/10/02/14/"&gt;http://www.cmaj.es/2007/10/02/14/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;"Transformaciones XSL (II): ¿Cuanto más rápidas son ahora?"&lt;/em&gt;. &lt;a href="http://www.cmaj.es/2007/10/10/transformaciones-xsl-rapidas-como-el-rayo-ii/"&gt;http://www.cmaj.es/2007/10/10/transformaciones-xsl-rapidas-como-el-rayo-ii/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;"Transformaciones XSL (III): No es oro todo lo que reluce"&lt;/em&gt;. &lt;a href="http://www.cmaj.es/2008/01/23/transformaciones-xsl-iii-no-es-oro-todo-lo-que-reluce/"&gt;http://www.cmaj.es/2008/01/23/transformaciones-xsl-iii-no-es-oro-todo-lo-que-reluce/&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;El "gato encerrado" descubierto en el tercer post hace que cada vez que reafirme más en esa sentencia que es recurrente en mis posts y conversaciones: &lt;strong&gt;si un framework deja dos opciones para hacer lo mismo, en el 50% de los casos se utilizará la incorrecta. Y lo que es peor, Murphy dice que el 100% de esas veces siempre pasa en proyectos más críticos y en sus peores fases.&lt;/strong&gt; Venga pongámosle nombre a esta ley... ¿qué tal la Ley del Chikilicuatre?&lt;/p&gt;&lt;p&gt;¿Por qué entonces, joder, nos empeñamos todos los arquitectos software en dejar para la posteriidad múltiples opciones de implementación o parametrización cuando rara vez tiene sentido algo distinto de la opción "lógica"? ¿para que los desarrolladores tengan más emoción en sus vidas????&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;P.D: [OFFTOPIC - Reflexión personal sobre el uso de XSLT]:&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;La tecnología XSLT es muy interesante desde el punto de vista teórico para independizar la capa de presentación de la tecnología concreta en que se desarrolla el resto de la aplicación. Es decir, en un mundo ideal podemos tener un equipo especializado 100% en XSLT + HTML + Javascript + AJAX, y que ese equipo intervenga tanto en proyectos Java, .NET, Python, RoR, PHP, o lo que sea. Yo mismo he apostado por esa estrategia en el pasado.&lt;/p&gt;&lt;p&gt;Pero esa es la teoría, la realidad dice que muy pocas Compañías pueden permitirse ese grado de equipos/perfiles especializados, más bien generalmente el 95% de tus proyectos son mono-tecnología (Java en mi caso) y en la Organización no existen los perfiles especializados sino genéricos o todoterreno. En ese caso una constante suele ser que el 100% de tus desarrolladores se sienten "javeros" (o lo que toque) y sorprendentemente les da "alergia" cualquier cosa distinta (y en ese saco meto tanto SQL como XSLT, HTML o Javascript)... y ahí tenemos un problema &lt;strong&gt;de cojones!&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Conclusión&lt;/strong&gt;: es mejor dejarse llevar por las fuertes corrientes e implementar la capa de presentación con Struts, JSF o lo que toque. Porque es lo que conocen los técnicos tanto de dentro como de fuera, y cuanto más distinto o especialito seas, más te cuesta sustituir a una persona o ampliar un equipo.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Corolario&lt;/strong&gt;: el uso de XSLT puede llegar a ser equivalente o superior en cuanto a rendimiento en tiempo de ejecución, pero siempre va a ser muy inferior en cuanto a rendimiento del equipo de trabajo. Al menos en un par de años vista...&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-3765029279659197042?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/3765029279659197042/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=3765029279659197042' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/3765029279659197042'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/3765029279659197042'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/06/rendimiento-en-transformaciones-xslt.html' title='Rendimiento en transformaciones XSLT'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_4ZEuwiCuF6A/SE4_-vRqwCI/AAAAAAAAACE/vjZOqL3cELg/s72-c/runtime_design.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-2729095309652625697</id><published>2008-06-06T20:33:00.007+02:00</published><updated>2008-12-10T12:55:16.657+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Sincronización'/><category scheme='http://www.blogger.com/atom/ns#' term='General'/><category scheme='http://www.blogger.com/atom/ns#' term='NIO'/><title type='text'>Mitos sobre rendimiento y escalabilidad</title><content type='html'>&lt;a href="http://1.bp.blogspot.com/_4ZEuwiCuF6A/SEbFiaNv0tI/AAAAAAAAABE/XAu4FQ2dZY0/s1600-h/myths_icon.gif"&gt;&lt;img id="BLOGGER_PHOTO_ID_5208067214043763410" style="FLOAT: left; MARGIN: 10px 10px 0px 0px; CURSOR: hand" alt="" src="http://1.bp.blogspot.com/_4ZEuwiCuF6A/SEbFiaNv0tI/AAAAAAAAABE/XAu4FQ2dZY0/s320/myths_icon.gif" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Una recopilación de buenos enlaces, ellos sí que saben. Y en la PPT va probablemente una de las mejores frases que he leído en meses: &lt;strong&gt;&lt;em&gt;"clever code confuses clever JVMs"&lt;/em&gt;&lt;/strong&gt;. o lo que es lo mismo "no te pases de listo" :-)&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Tengo que reconocer que alguno de los puntos de la PPT me ha sorprendido&lt;/strong&gt;, como que actualmente la sincronización en sí misma no es excesivamente costosa, sino que lo que sigue siendo costoso es la contención de threads. En otras palabras: en teoría "casi" es lo mismo usar un StringBuilder en lugar de StringBuffer cuando sólo un thread simultáneamente pasa por las regiones de exclusión mutua (lo que choca con lo que dije precisamente en uno de los primeros posts). ¿Es una gran equivocación o es que me estoy volviendo viejo y sigo tomando como ciertas cosas que eran verdad en la época del JDK 1.1, 1.2 y hasta 1.3 pero ya no lo son??? Si fuera verdad... ¿para qué crear la nueva StringBuilder? Ummm... Habrá que hacer pruebas de rendimiento (lo cierto es que en muchos aspectos casi todo el mundo habla de oídas)... &lt;em&gt;[Actualización 1/9/2008: puede verse información detallada acerca de benhmarking comparativo aplicando distintas opciones de lanzamiento de la JVM sobre esta y otras opciones de optimizaciones sobre el modelo de Threading en el post &lt;/em&gt;&lt;a href="http://serverperformance.blogspot.com/2008/09/funcionan-las-optimizaciones-sobre-el.html"&gt;&lt;em&gt;¿Funcionan las optimizaciones sobre el modelo de threading?&lt;/em&gt;&lt;/a&gt;&lt;em&gt;]&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;Y por cierto, como me han recordado hoy, &lt;b&gt;rendimiento no es sinónimo de escalabilidad&lt;/b&gt;. Hay que tener claros los conceptos y los objetivos en cada caso. En muchos casos los pasos para conseguir ambos objetivos son los mismos pero muchas otras veces son términos casi incompatibles. La cuestión es saber cuál es el término medio como siempre... &lt;ul&gt;&lt;li&gt;Mitos y leyendas (antiguos y actuales) sobre el rendimiento en Java. BUENÍSIMO: &lt;a href="http://www.cs.umd.edu/users/jmanson/java/presentations/sdwest2008.ppt"&gt;http://www.cs.umd.edu/users/jmanson/java/presentations/sdwest2008.ppt&lt;/a&gt; &lt;/li&gt;&lt;br /&gt;&lt;li&gt;¿Es de verdad la NIO no bloqueante mejor que la IO bloqueante "de toda la vida" para un servidor de aplicaciones? Los procesadores multicore cambian las reglas del juego:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://paultyma.blogspot.com/2008/03/writing-java-multithreaded-servers.html"&gt;http://paultyma.blogspot.com/2008/03/writing-java-multithreaded-servers.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://pphaneuf.livejournal.com/173745.html"&gt;http://pphaneuf.livejournal.com/173745.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://morningcofee.blogspot.com/2008/03/nio-io-debates.html"&gt;http://morningcofee.blogspot.com/2008/03/nio-io-debates.html&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://jutopia.tirsen.com/2008/03/07/threads-dont-scale-they-might-do-now/"&gt;http://jutopia.tirsen.com/2008/03/07/threads-dont-scale-they-might-do-now/&lt;/a&gt;&lt;a href="http://pphaneuf.livejournal.com/158639.html"&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Blog sobre concurrencia y sincronización. Un tío listo: &lt;a href="http://jeremymanson.blogspot.com/"&gt;http://jeremymanson.blogspot.com/&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;Y hablando de mitos y leyendas...&lt;a href="http://1.bp.blogspot.com/_4ZEuwiCuF6A/SEbF0aNv0uI/AAAAAAAAABM/kadCVatmchM/s1600-h/190TV_MythsAndLegendsElvis.gif"&gt;&lt;img id="BLOGGER_PHOTO_ID_5208067523281408738" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://1.bp.blogspot.com/_4ZEuwiCuF6A/SEbF0aNv0uI/AAAAAAAAABM/kadCVatmchM/s400/190TV_MythsAndLegendsElvis.gif" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-2729095309652625697?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/2729095309652625697/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=2729095309652625697' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/2729095309652625697'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/2729095309652625697'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/06/mitos-sobre-rendimiento-y-escalabilidad.html' title='Mitos sobre rendimiento y escalabilidad'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_4ZEuwiCuF6A/SEbFiaNv0tI/AAAAAAAAABE/XAu4FQ2dZY0/s72-c/myths_icon.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-1525213590319564647</id><published>2008-06-04T12:06:00.021+02:00</published><updated>2008-11-21T10:30:53.151+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JDK/JVM'/><category scheme='http://www.blogger.com/atom/ns#' term='JDBC/Oracle'/><title type='text'>JDBC 4.0 y Oracle 11G: combinación ganadora</title><content type='html'>&lt;a href="http://www.oreillynet.com/onjava/2006/08/02/graphics/111-jdbc.gif"&gt;&lt;img style="FLOAT: right; MARGIN: 0px 0px 10px 10px; CURSOR: hand" alt="" src="http://www.oreillynet.com/onjava/2006/08/02/graphics/111-jdbc.gif" border="0" /&gt;&lt;/a&gt;La versión 4.0 de JDBC, incorporado en Java SE 6.0, supone un salto importante en cuanto a rendimiento en muchos pequeños aspectos. Uno de ellos es la mejora en los pooles, y otro ejemplo -en el que me voy a centrar hoy- son los LOBs. Este artículo no pretende ser un estudio exhaustivo acerca de JDBC 4.0, para eso mejor visitar por ejemplo algunos de los enlaces de abajo (en concreto el de onjava.com o el de ibm-developerworks).&lt;br /&gt;&lt;br /&gt;Estas mejoras pueden no ser significativas en algunos/muchos entornos, pero sí que lo son en servidores con mucho estrés o en temas muy concretos como el uso de LOBs, que por fin se pueden gestionar de una forma coherente y sencilla.&lt;br /&gt;&lt;br /&gt;Por ejemplo, se han añadido a PreparedStatement los métodos:&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-family:courier new;"&gt;/**&lt;br /&gt;* Sets the designated parameter to a &lt;code&gt;InputStream&lt;/code&gt; object. The inputstream must contain the number&lt;br /&gt;* of characters specified by length otherwise a &lt;code&gt;SQLException&lt;/code&gt; will be&lt;br /&gt;* generated when the &lt;code&gt;PreparedStatement&lt;/code&gt; is executed.&lt;br /&gt;* This method differs from the &lt;code&gt;setBinaryStream (int, InputStream, int)&lt;/code&gt;&lt;br /&gt;* method because it informs the driver that the parameter value should be&lt;br /&gt;* sent to the server as a &lt;code&gt;BLOB&lt;/code&gt;. When the &lt;code&gt;setBinaryStream&lt;/code&gt; method is used,&lt;br /&gt;* the driver may have to do extra work to determine whether the parameter&lt;br /&gt;* data should be sent to the server as a &lt;code&gt;LONGVARBINARY&lt;/code&gt; or a &lt;code&gt;BLOB&lt;/code&gt;&lt;br /&gt;* @param parameterIndex index of the first parameter is 1,&lt;br /&gt;* the second is 2, ...&lt;br /&gt;* @param inputStream An object that contains the data to set the parameter&lt;br /&gt;* value to.&lt;br /&gt;* @param length the number of bytes in the parameter data.&lt;br /&gt;* @throws SQLException if parameterIndex does not correspond to a parameter&lt;br /&gt;* marker in the SQL statement; if a database access error occurs;&lt;br /&gt;* this method is called on a closed &lt;code&gt;PreparedStatement&lt;/code&gt;;&lt;br /&gt;* if the length specified&lt;br /&gt;* is less than zero or if the number of bytes in the inputstream does not match&lt;br /&gt;* the specfied length.&lt;br /&gt;* @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method&lt;br /&gt;*&lt;br /&gt;* @since 1.6&lt;br /&gt;*/&lt;br /&gt;&lt;code&gt;void &lt;strong&gt;setBlob&lt;/strong&gt;(int parameterIndex, InputStream inputStream, long length)&lt;br /&gt;throws SQLException;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* Sets the designated parameter to a &lt;code&gt;Reader&lt;/code&gt; object. The reader must contain the number&lt;br /&gt;* of characters specified by length otherwise a &lt;code&gt;SQLException&lt;/code&gt; will be&lt;br /&gt;* generated when the &lt;code&gt;PreparedStatement&lt;/code&gt; is executed.&lt;br /&gt;* This method differs from the &lt;code&gt;setCharacterStream (int, Reader, int)&lt;/code&gt; method&lt;br /&gt;* because it informs the driver that the parameter value should be sent to&lt;br /&gt;* the server as a &lt;code&gt;CLOB&lt;/code&gt;. When the &lt;code&gt;setCharacterStream&lt;/code&gt; method is used, the&lt;br /&gt;* driver may have to do extra work to determine whether the parameter&lt;br /&gt;* data should be sent to the server as a &lt;code&gt;LONGVARCHAR&lt;/code&gt; or a &lt;code&gt;CLOB&lt;/code&gt;&lt;br /&gt;* @param parameterIndex index of the first parameter is 1, the second is 2, ...&lt;br /&gt;* @param reader An object that contains the data to set the parameter value to.&lt;br /&gt;* @param length the number of characters in the parameter data.&lt;br /&gt;* @throws SQLException if parameterIndex does not correspond to a parameter&lt;br /&gt;* marker in the SQL statement; if a database access error occurs; this method is called on&lt;br /&gt;* a closed &lt;code&gt;PreparedStatement&lt;/code&gt; or if the length specified is less than zero.&lt;br /&gt;*&lt;br /&gt;* @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method&lt;br /&gt;* @since 1.6&lt;br /&gt;*/&lt;br /&gt;&lt;code&gt;void &lt;strong&gt;setClob&lt;/strong&gt;(int parameterIndex, Reader reader, long length)&lt;br /&gt;throws SQLException;&lt;/code&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;Esto implica que, con bases de datos Oracle, nunca más sea necesaria la creación de un blob temporal a través de la API propia de Oracle y posterior asignación a la nueva fila sin que de forma mucho más intuitiva y estándar podemos hacer lo siguiente para insertar datos en una columna de tipo BLOB:&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-family:courier new;"&gt;&lt;code&gt;File originalFile = new File(PATH);&lt;br /&gt;Connection conn = ...;&lt;br /&gt;PreparedStatement ps = conn.prepareStatement("...");&lt;br /&gt;ps.setBlob(1, new FileInputStream(originalFile), originalFile.length());&lt;br /&gt;ps.execute();&lt;br /&gt;ps.close();&lt;br /&gt;conn.close();&lt;/code&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;No sólo es más elegante, sino que en Oracle 11G supone un incremento de hasta un 25% en el rendimiento frente al tradicional método con "BLOB.createTemporary()" propietario de Oracle (son mis datos empíricos con ficheros de más de 10 megas). Lo cual sumado al uso de los nuevos &lt;strong&gt;SECUREFILEs&lt;/strong&gt; para almacenar LOBS, &lt;strong&gt;significa que la combinación Java 6 + JDBC 4 + Oracle 11G suponga hasta casi un 50% más de rendimiento que Java SE 1.5 + JDBC 3 + Oracle 10G en la inserción de LOBs de gran tamaño&lt;/strong&gt;.&lt;br /&gt;&lt;br /&gt;Para más información acerca de los cambios que supone JDBC 4 sobre sus antecedores:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://java.sun.com/javase/technologies/database/index.jsp"&gt;http://java.sun.com/javase/technologies/database/index.jsp&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://java.sun.com/javase/6/docs/technotes/guides/jdbc/blob.html"&gt;http://java.sun.com/javase/6/docs/technotes/guides/jdbc/blob.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.onjava.com/pub/a/onjava/2006/08/02/jjdbc-4-enhancements-in-java-se-6.html"&gt;http://www.onjava.com/pub/a/onjava/2006/08/02/jjdbc-4-enhancements-in-java-se-6.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.ibm.com/developerworks/db2/library/techarticle/dm-0708calio/index.html"&gt;http://www.ibm.com/developerworks/db2/library/techarticle/dm-0708calio/index.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.artima.com/lejava/articles/jdbc_four.html"&gt;http://www.artima.com/lejava/articles/jdbc_four.html&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-1525213590319564647?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/1525213590319564647/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=1525213590319564647' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/1525213590319564647'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/1525213590319564647'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/06/jdbc-4-y-oracle-11g-combinacin-ganadora.html' title='JDBC 4.0 y Oracle 11G: combinación ganadora'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-3076111230946613282</id><published>2008-06-02T10:06:00.024+02:00</published><updated>2008-11-21T10:32:25.367+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Strings/Buffers/Ficheros'/><category scheme='http://www.blogger.com/atom/ns#' term='XML/SOAP'/><category scheme='http://www.blogger.com/atom/ns#' term='Benchmarks'/><title type='text'>Javolution</title><content type='html'>&lt;a href="http://www.xml.com/2007/05/09/Graphics/all_stax_middle.png"&gt;&lt;img style="FLOAT: right; MARGIN: 0px 0px 10px 10px; WIDTH: 320px; CURSOR: hand" alt="" src="http://www.xml.com/2007/05/09/Graphics/all_stax_middle.png" border="0" /&gt;&lt;/a&gt; &lt;a href="http://javolution.org/"&gt;http://javolution.org/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;¿Operaciones de inserción en strings de orden logarítmico en lugar de lineal? &lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;¿Alguien que por fin se acuerda de optimizar específicamente los marshallings/unmarshailling de XML? &lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;Eso mola...&lt;/strong&gt;&lt;br /&gt;&lt;p&gt;Se trata de una biblioteca de clases básicas, muchas de ellas "sustitutivas" de las que vienen en la biblioteca estándar del JDK, cuyo principal objetivo es el alto rendimiento y la predictibilidad (determinismo) del mismo. Principalmente pensada inicialmente para sistemas de tiempo real y empotrados, aunque como puede verse también puede ser de gran utilidad en sistemas servido con mucha concurrencia o necesidades de rendimiento y escalabilidad.&lt;/p&gt;&lt;p&gt;La biblioteca estándar del JDK tiene un problema general: está pensada para no dar problemas en ningún entorno, por lo que puede no ser la mejor solución siempre. Por ejemplo, la mayor parte de las clases son &lt;em&gt;threadsafe&lt;/em&gt;, lo cual significa que por ejemplo la concatenación en un StringBuffer o el uso de una tabla de hash está lleno de regiones de exclusión mutua y uso de monitores. Siendo que en el 95% de los casos son completamente innecesarias debido a que hoy en día un desarrollador trabaja dentro de un framework, o genera código para un EJB, etc, y ese objeto sólo va a ser ejecutado por un thread en cada momento.&lt;/p&gt;&lt;p&gt;Por supuesto, con el tiempo Java ha evolucionado en dos líneas:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Por un lado cada revisión de la máquina virtual / Hotspot VM hace que se reduzca la penalización por el uso de monitores allá donde no hacían falta.&lt;/li&gt;&lt;li&gt;Por otro lado, poco a poco en el JDK se han ido introduciendo versiones "no sincronizadas". Por la propia filosofía de compatibilidad hacia atrás, el tema va quedando al menos "raro", pero es lo que hay. Por ejemplo:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;java.uti.HashMap&lt;/code&gt; (que ofrece la misma funcionalidad que la java.util.Hashtable de toda la vida).&lt;/li&gt;&lt;li&gt;&lt;code&gt;java.lang.StringBuilder&lt;/code&gt; por fin desde el JDK 1.6 supone una alternativa "no sincronizada" al infame java.lang.StringBuffer. (¿De verdad nadie se había dado cuenta hasta ahora que en el 99,999999% de las veces la concatenación de cadenas se usa en un contexto threadsafe?????)&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;p&gt;El problema de separar así la API es que estás delegando en la capacidad, memoria, experiencia y entrenamiento del desarrollador. Mi experiencia dicta que &lt;em&gt;"si quieres que algo se haga de una cierta forma, no des dos opciones para ello; en un 50% de los casos se utilizará la incorrecta"&lt;/em&gt;. No sé si hay una ley para ello, o si no le ponemos un nombre. Claro que para que tenga éxito la postulación tenemos que poner mejor las cantidades 80-20 por algún lado ;-)&lt;/p&gt;&lt;p&gt;En esta línea llega &lt;strong&gt;Javolution&lt;/strong&gt;. Me gusta, y mucho. Probablemente porque es lo que yo siempre he querido hacer, probablemente porque me he enamorado de su código fuente.&lt;/p&gt;&lt;p&gt;Pero tiene una pega, probablemente insalvable: en el fondo lo mismo que comento arriba: se trata de algo nuevo que aprender, no estándar y que los desarrolladores que hay en el mercado y entran nuevos a tu equipo no están habituados a utilizar. Es decir, mal rollo salvo que se utilice en un contexto muy concreto dentro de un producto o exclusivamente en las partes críticas de un proyecto. &lt;/p&gt;&lt;p&gt;También tiene otra pega que he sufrido yo en intentos similares anteriores: las siguientes revisiones de la JVM o del JDK pueden hacer inservibles parte de las optimizaciones, o que se optimicen las clases estándar más allá de la línea que ha podido seguir Javolution.&lt;/p&gt;&lt;p&gt;Y finalmente: hay que saber lo que está haciendo. Hay que "ayudar" a las optimizaciones de forma declarativa indicando contextos de trabajo... Y no me gusta tener la obligación de que todo desarrollador de un equipo sea un auténtico experto en rendimiento o cuncurrencia.&lt;/p&gt;&lt;p&gt;Más que reconmendable, sobre todo en sistemas de tiempo real, pero teniendo siempre presente que no existen los milagros (sino que lo importante es la suma de muchos pequeños detalles) y también en cuenta las reflexiones de arriba ("gato escaldado del agua fría huye").&lt;/p&gt;&lt;p&gt;Como muestra un botón: benchmarking de parsers XML --&lt;a href="http://www.xml.com/pub/a/2007/05/09/xml-parser-benchmarks-part-1.html?page=2"&gt;http://www.xml.com/pub/a/2007/05/09/xml-parser-benchmarks-part-1.html?page=2&lt;/a&gt;&lt;/p&gt;&lt;p&gt;En cualquier caso, mi conclusión es:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Utilizarlo sólo en los proyectos y contextos en que sea inevitable, o crítico&lt;/li&gt;&lt;li&gt;Muy interesante para conocerlo y aprender de por qué y cómo está hecho&lt;/li&gt;&lt;li&gt;Muy interesante para que los señores que desarrollan el JDK (ahora es Open Source así que debería estar más abierto a ideas frescas), así como implementadores de las APIs más comunes y equipos de desarrollo de servidores de aplicaciones varios &lt;/li&gt;&lt;li&gt;Muchas veces de nada serviría utilizarlo en nuestro proyecto, si no lo aplica el servidor de aplicaciones que hay por debajo, y que también habría que meterle mano para que realmente se note un cambio en la tendencia de respuesta o rendimiento.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Por cierto, que en la documentación de la API puede verse unos gráficos comparativos de tiempos de resupuesta de cada clase frente a su "competidora" en el JDK...&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;a href="http://javolution.org/"&gt;&lt;img src="http://javolution.org/css/img/javolution.png" /&gt;&lt;/a&gt; &lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-3076111230946613282?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/3076111230946613282/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=3076111230946613282' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/3076111230946613282'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/3076111230946613282'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/06/javolution.html' title='Javolution'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-1414844461413692537</id><published>2008-05-30T20:30:00.022+02:00</published><updated>2009-04-17T11:48:56.353+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='iPlanet'/><category scheme='http://www.blogger.com/atom/ns#' term='HTTP/S'/><category scheme='http://www.blogger.com/atom/ns#' term='Glassfish/Tomcat'/><category scheme='http://www.blogger.com/atom/ns#' term='Apache'/><category scheme='http://www.blogger.com/atom/ns#' term='GZIP'/><title type='text'>Compresión HTTP</title><content type='html'>&lt;img id="BLOGGER_PHOTO_ID_5236901518841736322" style="FLOAT: left; MARGIN: 0px 10px 10px 0px" alt="" src="http://2.bp.blogspot.com/_4ZEuwiCuF6A/SK02L2JD7II/AAAAAAAAAEU/trpjEeV5y-U/s320/screenshot.png" border="0" /&gt;&lt;em&gt;[Actualizado Oct'08 para corregir la parte de XML de configuración de Glassfish, el editor de Blogger me había cortado algunas cosas... :-(]&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;Es increíble que a día de hoy, año 2008, todavía un gran porcentaje de sitios y servicios web no tengan implementada ni la optimización más básica de todas: compresión de los contenidos servidos para aligerar las comunicaciones.&lt;br /&gt;&lt;br /&gt;¿Por qué Google es el buscador más rápido? ¿por qué eBankinter es la banca online más rápida? Por mil cosas, y una de ellas es esta, claro. Y otra es la correcta gestión de las cabeceras de expiración de contenidos, pero eso puede que sea objeto de otra entrada... :-)&lt;br /&gt;&lt;br /&gt;El protocolo HTTP lo soporta desde "casi siempre" y los navegadores también, incluso aquellos Netscape 4 e internet Explorer 4 de los que ya no nos acordamos y que tantos quebraderos de cabeza nos dieron hace unos añitos... Y el protocolo FTP también lo soporta (el llamado "Z Mode").&lt;br /&gt;&lt;br /&gt;No voy a entrar en las posibilidades o particularidades, o en qué situaciones es más perjudicial que beneficioso porque al fin y al cabo consumimos recursos de procesamiento tanto en cliente como en servidor (por lo general en aplicaciones de Intranet en las que el ancho de banda es realmente alto). Pero, por lo general un fichero HTML normalito tiene una tasa de compresión con GZIP de entre 5:1 y 15:1. O lo que es lo mismo, una página de 200 KByes puede suponer que en realidad al navegador transmitamos sólo 20 KBytes. Y eso no sólo es importante en términos de visitantes unitarios, sino en términos de ancho de banda servidor en situaciones de concurrencia importante.&lt;br /&gt;&lt;br /&gt;El protocolo HTTP, por ejemplo, define un diálogo muy sencillo entre el cliente (navegador) y el servidor, para el primero informe al segundo de sus "capacidades" y el segundo informe al primero de si el contenido está comprimido o no. Se hace a través de las cabeceras HTTP. Por ejemplo:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;Header en la petición:&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;code&gt;    Accept-Encoding: gzip, deflate&lt;/code&gt;&lt;/span&gt;&lt;br /&gt;Headers en la respuesta:&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;code&gt;    Vary: Accept-Encoding&lt;br /&gt;    Content-Encoding: gzip&lt;/code&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;¿Mola? Pues es trivial de implementar. Tanto el IIS como Apache Web Server (a través de mod_deflate o mod_gzip) como Glassfish, Tomcat, Orion, etc, etc, lo soportan.&lt;br /&gt;&lt;br /&gt;Algunos ejemplos sencillos.&lt;br /&gt;&lt;br /&gt;En &lt;strong&gt;Tomcat&lt;/strong&gt; basta con añadir al tag &lt;code&gt;&amp;lt;Connector&amp;gt;&lt;/code&gt; del fichero server.xml: &lt;blockquote&gt;&lt;span style="font-family:courier new;"&gt;&lt;code&gt;compression="on"&lt;br /&gt;compressableMimeType="text/html,text/xml,text/css,text/javascript,text/plain,application/x-javascript,text/unknown,text/*"&lt;/code&gt;&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;En &lt;strong&gt;Glassfish&lt;/strong&gt; basta con añadir lo equivalente en el &lt;code&gt;domain.xml&lt;/code&gt;, dentro de las secciones &lt;code&gt;&amp;lt;http-listener&amp;gt;&lt;/code&gt; que deseemos: &lt;blockquote&gt;&lt;span style="font-family:courier new;"&gt;&lt;code&gt;&amp;lt;property name="compression" value="on"/&amp;gt;&lt;br /&gt;&amp;lt;property name="compressableMimeType" value="text/html,text/xml,text/css,text/javascript,text/plain,application/x-javascript,application/force-download,application/pdf,text/unknown,text/*"/&amp;gt;&lt;/code&gt;&lt;/span&gt;&lt;/blockquote&gt;En &lt;strong&gt;Apache&lt;/strong&gt; es también trivial; por ejemplo en Apache 2.2 con mod_deflate la configuración sería: &lt;blockquote&gt;&lt;span style="font-family:courier new;"&gt;&lt;code&gt;AddOutputFilterByType DEFLATE text/html text/xml text/css text/javascript text/plain application/x-javascript application/force-download application/pdf text/unknown text/* &lt;/code&gt;&lt;/span&gt;&lt;/blockquote&gt;En &lt;strong&gt;iPlanet&lt;/strong&gt; idem, además se permite tanto la carga de archivos "precomprimidos" y la compresión al vuelo. Para la compresión dinámica: &lt;blockquote&gt;&lt;span style="font-family:courier new;"&gt;&lt;code&gt;Output fn="insert-filter" filter="http-compression" type="text/*" vary="on"&lt;br /&gt;Output fn="insert-filter" filter="http-compression" type="application/x-javascript" vary="on"&lt;br /&gt;Output fn="insert-filter" filter="http-compression" type="application/force-download" vary="on"&lt;br /&gt;Output fn="insert-filter" filter="http-compression" type="application/pdf" vary="on"&lt;br /&gt;&lt;/code&gt;&lt;/span&gt;&lt;/blockquote&gt;Y para soporte a archivos precomprimidos en iPlanet (deben existir las dos versiones, por ejemplo "prueba.js" y "prueba.js.gz"). Aquí habrá que hacerlo por cada extensión o similar (no es un filtro de salida sino un procesamiento previo, por ejemplo para aplicarlos a ficheros .js:&lt;blockquote&gt;&lt;span style="font-family:courier new;"&gt;&lt;code&gt;&amp;lt;Object ppath="*/*.js"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;PathCheck fn="find-compressed" check-age="on" vary="on"&lt;br /&gt;&amp;lt;/Object&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Hay unas cuantas opciones que considerar (como el tamaño mínimo de un fichero para que lo comprima, o si debe ignorar algunos navegadores) e instrucciones a los proxy caches para indicarle que este contenido es una variante (es decir que envíe la cabecera &lt;code&gt;Vary: Accept-Encoding&lt;/code&gt;), pero básicamente ahí está...&lt;br /&gt;&lt;br /&gt;Además de compresión por software, se puede utilizar hardware de aceleración especializado para ello, pero eso también será objeto de otra entrada...&lt;br /&gt;&lt;br /&gt;Algunos links de interés:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html"&gt;http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.websiteoptimization.com/"&gt;http://www.websiteoptimization.com/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://weblogs.java.net/blog/jfarcand/archive/2006/06/enabling_http_c_1.html"&gt;http://weblogs.java.net/blog/jfarcand/archive/2006/06/enabling_http_c_1.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.sendung.de/archives/2007/04/09/web-services-output-formats-and-gzip-compression/"&gt;http://www.sendung.de/archives/2007/04/09/web-services-output-formats-and-gzip-compression/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://softwarecommunity.intel.com/articles/eng/2585.htm"&gt;http://softwarecommunity.intel.com/articles/eng/2585.htm&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-1414844461413692537?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/1414844461413692537/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=1414844461413692537' title='3 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/1414844461413692537'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/1414844461413692537'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/05/compresin-http.html' title='Compresión HTTP'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SK02L2JD7II/AAAAAAAAAEU/trpjEeV5y-U/s72-c/screenshot.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-8135107141018917736</id><published>2008-05-30T17:37:00.007+02:00</published><updated>2008-12-10T12:55:16.892+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='General'/><title type='text'>Disclaimers</title><content type='html'>&lt;a href="http://2.bp.blogspot.com/_4ZEuwiCuF6A/SEZzFqNv0mI/AAAAAAAAAAM/qOqa3EKs7Ns/s1600-h/disclaimer.gif"&gt;&lt;img id="BLOGGER_PHOTO_ID_5207976560169046626" style="FLOAT: left; MARGIN: 0px 10px 10px 0px; CURSOR: hand" alt="" src="http://2.bp.blogspot.com/_4ZEuwiCuF6A/SEZzFqNv0mI/AAAAAAAAAAM/qOqa3EKs7Ns/s320/disclaimer.gif" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div&gt;&lt;strong&gt;EN NINGUNO DE LOS CASOS LAS OPINIONES EXPRESADAS REFLEJAN LA POSICIÓN DE MI EMPRESA O DE NINGUNA DE LAS ORGANIZACIONES PARA LAS QUE COLABORE O HAYA COLABORADO. Los ejemplos o situaciones descritas son absolutamente inventadas y cualquier parecido con la realidad es mera coincidencia. &lt;/strong&gt;(Siempre quise decir esa frase)&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Este blog no tiene ningún fin lucrativo o comercial, sino meramente de bitácora y divulgativo. En las entradas del mismo pueden mencionarse -sin intención publicitaria ni vinculación alguna con sus propietarios- productos y/o marcas comerciales registradas por sus propietarios. Si en algún caso dicho propietario entiende que se están vulnerando sus derechos o prefiere que se elimine alguna referencia o comentario, ruego se pongan en contacto conmigo.&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Del mismo modo, algunas de las imágenes incluidas pueden tener derechos de autor, de modo que de nuevo ruego a sus propietarios que se pongan en contacto conmigo si se desea retirar alguna de ellas.&lt;/strong&gt; &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-8135107141018917736?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/8135107141018917736/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=8135107141018917736' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/8135107141018917736'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/8135107141018917736'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/05/disclaimers.html' title='Disclaimers'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SEZzFqNv0mI/AAAAAAAAAAM/qOqa3EKs7Ns/s72-c/disclaimer.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1376283136035918844.post-3221519602086579576</id><published>2008-05-30T15:56:00.015+02:00</published><updated>2008-06-11T17:38:44.777+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='General'/><title type='text'>Introducción</title><content type='html'>&lt;strong&gt;Bienvenido a mi espacio de reflexiones.&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Mi objetivo con este blog es publicar mis reflexiones anónimas sobre mis áreas de interés, conforme vaya surgiendo la oportunidad dentro de mis responsabilidades profesionales.&lt;br /&gt;&lt;br /&gt;Llevo unos cuantos años relacionado profesionalmente de una forma u otra con tecnologías internet, y fui uno de los pioneros en España en el uso de Java en general (JDK 1.0 y 1.1 allá por 1997) y de los EJB 1.0 en particular (allá por finales de 1999). Eso son más de 11 años a día de hoy.&lt;br /&gt;&lt;br /&gt;Actualmente lidero un equipo técnico dedicado al desarrollo de soluciones servidor en Java EE, abarcando distintas líneas de actuación. A lo largo del tiempo van surgiendo nuevos problemas (o se van reitiendo patrones antiguos) relacionados con el rendimiento de los servidores, de la base de datos, del propio desarrollo Java EE, de HTTP/S, de SOAP, de los nuevos paradigmas RIA/AJAX... de modo que mi objetivo es ir recogiendo a modo de bitácora esos elementos.&lt;br /&gt;&lt;br /&gt;Por experiencias pasadas, no pienso comprometerme a escribir con regularidad ni a hacerlo en profundidad. He tomado mucho de otros gracias a la gran telaraña, si además de servir de memoria personal estas reflexiones pueden servirles a otros, bienvenido sea!!!&lt;br /&gt;&lt;br /&gt;Me encantaría escribir las entradas también en inglés, pero mis limitaciones hacen que lo haga sólo en el idioma de Cervantes...&lt;br /&gt;&lt;br /&gt;Saludos,&lt;br /&gt;&lt;em&gt;--Server performance&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="https://duke.dev.java.net/images/JDK6/DukeWithHelmet.png"&gt;&lt;img style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="https://duke.dev.java.net/images/JDK6/DukeWithHelmet.png" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1376283136035918844-3221519602086579576?l=serverperformance.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serverperformance.blogspot.com/feeds/3221519602086579576/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1376283136035918844&amp;postID=3221519602086579576' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/3221519602086579576'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1376283136035918844/posts/default/3221519602086579576'/><link rel='alternate' type='text/html' href='http://serverperformance.blogspot.com/2008/05/introduccin.html' title='Introducción'/><author><name>serverperformance</name><uri>http://www.blogger.com/profile/05852682480069888278</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_4ZEuwiCuF6A/SPSEUlY9aqI/AAAAAAAAAG8/m_6sHwSlxTo/S220/ImpulseLogo.png'/></author><thr:total>0</thr:total></entry></feed>
