miércoles, 25 de marzo de 2009

Un medio, no un fin

Sin que sirva de precedente tiene poco que ver con el tema de este blog (o mucho si se piensa bien).

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):

"Ejecutivos y gerentes se esfuerzan por satisfacer las necesidades de los clientes y de los accionistas de manera simultánea"
(http://files.epsscentral.info/gery/pdfarticles/Enterprise%20Nervous%20System.pdf)
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.

Aunque para obtener ese objetivo como precio a pagar haya que satisfacer al cliente. Esta frase es de otro sabio, Zipi ;-)

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...

¡Qué gran pareja estos Zipi y Zape! Lástima que siguieran sus carreras musicales por separado...

Y aplicado a la temática de este blog: el rendimiento y escalabilidad es un medio, no un fin.

:-/

viernes, 20 de marzo de 2009

SaaS, IaaS y PaaS: Las tres clases de Cloud Computing

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.

Esta es la única catalogación clara que hay por ahí en castellano, en Nubeblog:

http://www.nubeblog.com/2008/10/15/saas-iaas-y-paas-las-tres-clases-de-cloud-computing/
Claro y conciso. De verdad.

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 :-)

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...

viernes, 13 de marzo de 2009

Compressed pointers. Compressed oops.

Una de mis optimizaciones favoritas que aparecerán en la update 14 de Java 6 (actualmente en build 1, como os indiqué en un artículo anterior), y que ya estaba disponible en las "performance releases" es la compresión de punteros en la máquina virtual de 64 bits.

En Sun le llaman "compressed oops".

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: "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."

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.

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...

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), no es cierto. 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.

¿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...

Más información sobre compresión de punteros, el primer enlace es el clarificador:

viernes, 6 de marzo de 2009

Los finalizers no son tus amigos (parte II)

Juro por la gloria de que James Gosling que ha sido casualidad... Al hilo de lo que comentábamos el lunes... [Viene del artículo anterior: Los finalizers no son tus amigos]

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???

El webrev completo puede verse en: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/da9d0283a496

La descripción es:
Issue: SSL stress test with GF leads to 32 bit max process size in less than 5 minutes with PCKS11 provider.
Summary: Removed finalize() and add more error handling to native code.

Author: valerie
Reviewed-by: vinnie

lunes, 2 de marzo de 2009

Los finalizers no son tus amigos

Gracias al artículo de este mes de javaspecialists.eu (http://www.javaspecialists.eu/archive/Issue170.html), he redescubierto que hay que evitar la implementación del método finalize() siempre que sea posible.

¿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.

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)? :-)

Si sigues estando seguro de que lo necesitas, dos comentarios:
  1. 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.
  2. 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.
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: sólo se añaden hooks a objetos con finalizadores no triviales.

Más información:

Ahora repite conmigo:
Los finalizers no son mis amigos.... Finalizer malo, finalizer malo...

[Continúa en el siguiente post: Los finalizers no son tus amigos (parte II)]