tabulador secuencias salto retorno representacion linea escape escapar como carro java stack allocation escape-analysis

salto - secuencias de escape java



AnĂ¡lisis de escape en Java (3)

Con esta versión de java -XX: + DoEscapeAnalysis da como resultado mucha menos actividad de gc y una ejecución 14 veces más rápida.

$ java -version java version "1.6.0_14" Java(TM) SE Runtime Environment (build 1.6.0_14-b08) Java HotSpot(TM) Client VM (build 14.0-b16, mixed mode, sharing) $ uname -a Linux xxx 2.6.18-4-686 #1 SMP Mon Mar 26 17:17:36 UTC 2007 i686 GNU/Linux

Sin análisis de escape,

$ java -server -verbose:gc EscapeAnalysis|cat -n 1 start 2 [GC 896K->102K(5056K), 0.0053480 secs] 3 [GC 998K->102K(5056K), 0.0012930 secs] 4 [GC 998K->102K(5056K), 0.0006930 secs] --snip-- 174 [GC 998K->102K(5056K), 0.0001960 secs] 175 [GC 998K->102K(5056K), 0.0002150 secs] 176 10000000

Con el análisis de escape,

$ java -server -verbose:gc -XX:+DoEscapeAnalysis EscapeAnalysis start [GC 896K->102K(5056K), 0.0055600 secs] 10000000

El tiempo de ejecución se reduce significativamente con el análisis de escape. Para esto, el ciclo se cambió a 10e9 iteraciones,

public static void main(String [] args){ System.out.println("start"); for(int i = 0; i < 1000*1000*1000; ++i){ Foo foo = new Foo(); } System.out.println(Foo.counter); }

Sin análisis de escape,

$ time java -server EscapeAnalysis start 1000000000 real 0m27.386s user 0m24.950s sys 0m1.076s

Con el análisis de escape,

$ time java -server -XX:+DoEscapeAnalysis EscapeAnalysis start 1000000000 real 0m2.018s user 0m2.004s sys 0m0.012s

Entonces, con el análisis de escape, el ejemplo corrió aproximadamente 14 veces más rápido que la ejecución de análisis sin escape.

Por lo que yo sé, la JVM usa el análisis de escape para algunas optimisations rendimiento, como bloqueo de engrosamiento y bloqueo de elisión. Me interesa si existe la posibilidad de que la JVM decida que cualquier objeto en particular se puede asignar en la pila mediante el análisis de escape.

Algunos resources me hacen pensar que tengo razón. ¿Hay JVM que realmente lo hacen?


El análisis de escape es muy bueno, pero no es una obtención completa de la tarjeta sin cárcel. si tiene una colección de tamaño dinámico dentro de un objeto, el análisis de escape NO cambiará de pila a pila. Por ejemplo:

public class toEscape { public long l; public List<Long> longList = new ArrayList<Long>(); }

Incluso si este objeto se crea en un método y NO escapa desde un punto de vista sintáctico, el compilador no lo marcará como escape. Sospecho que debido a que longList no está realmente limitado en tamaño desde una perspectiva sintáctica pura y podría explotar tu pila potencialmente. Por lo tanto, creo que se necesita un pase en este caso. Experimenté con esto donde el longList estaba vacío y todavía causó colecciones en un micro benchmark simple.


No creo que escape el análisis para la asignación de la pila. ejemplo:

public class EscapeAnalysis { private static class Foo { private int x; private static int counter; public Foo() { x = (++counter); } } public static void main(String[] args) { System.out.println("start"); for (int i = 0; i < 10000000; ++i) { Foo foo = new Foo(); } System.out.println(Foo.counter); } }

con -server -verbose:gc -XX+DoEscapeAnalysis :

start [GC 3072K->285K(32640K), 0.0065187 secs] [GC 3357K->285K(35712K), 0.0053043 secs] [GC 6429K->301K(35712K), 0.0030797 secs] [GC 6445K->285K(41856K), 0.0033648 secs] [GC 12573K->285K(41856K), 0.0050432 secs] [GC 12573K->301K(53952K), 0.0043682 secs] [GC 24877K->277K(53952K), 0.0031890 secs] [GC 24853K->277K(78528K), 0.0005293 secs] [GC 49365K->277K(78592K), 0.0006699 secs] 10000000

Supuestamente, JDK 7 admite la asignación de pila .