2010-05-26 9 views
7

En mi trabajo, recientemente terminamos la arquitectura del sistema para una aplicación de control que tiene una latencia máxima de aproximadamente uno o dos segundos. Se distribuye en pequeños cuadros ARM en chip que se comunican a través de una LAN IP.~ 1s aplicación de control de latencia: ¿es adecuado para Java?

Inicialmente prevemos que usaríamos C o C++, ya que es un lenguaje de sistema de control clásico. Después de analizar cómo implementar la aplicación, ahora nos damos cuenta de que C++ tiene una cantidad bastante limitada de bibliotecas, carece de introspección y tiene otras propiedades que pueden ralentizar el desarrollo. Mi colega sugirió que Java podría estar listo para el trabajo.

Tengo mucho miedo por la latencia de ejecutar un GC para una aplicación de control, y también soy reacio a descartar RAII, ya que la aplicación usará muchos recursos externos (sockets, manejadores de archivos, identificadores externos libs, etc.).

La lista de/con pro es actualmente de la siguiente manera:

C++ 

+ RAII - Easy resource management - it will be a complex system 
+ System language - speed if we cant't find a JIT VM for our ARM 
+ No GC - no big worst case latencies from the GC 
+ Easy to integrate with some shared mem libs that we have to interface with 
- Fewer free as in beer libs 
- Lacks introspection - Mapping classes to DB and external data formats (XML)  
    would benefit from this (ORM /JAXB) approach 
- Easy to shoot one self in the foot - hard and expensive to find programmers 
    which don't make big mistakes 
- Memory fragmentation - needs tuning and workarounds 

Java 

+ Huge amount of libs 
+ Introspection - serialization becomes a breeze (see C++ section) 
+ Easier to find 'good enough' programmers 
- No RAII - Client has to remember finally or you leak 
    resources. IMO Java programmers tend to ignore this 
    problem unless they have server app background. 
- No System Language - possibly slower although ARMj could alleviate this 
- GC - latency might go up (don't know if parallel GC will work - seems that 
    you might get fragmentation, see note below). 
- Need to write JNI for the shared mem libs that we interface with 
- Maybe ORACLE will eat us 

La fragmentación de la memoria con GC paralelo se mencionó in this AMD article

me gustaría utilizar Java si la latencia de GC no era un problema, y ​​nos podría obtener RAII. Por lo tanto, también he investigado otras langs que tienen RAII y podrían servir como buenas alternativas, y hasta ahora he descubierto que D, Ada, VB, Perl, Python (C), PHP, tcl y Lua parecen tener algunas tipo de devolución de llamada fuera de alcance. Mi reacción espontánea es que tal vez D, Python y ADA podrían ser adecuados para una aplicación de control. D y ADA son mis favoritos.

Entonces, mi pregunta es: ¿tiene alguna recomendación al respecto? ¿Es Java una opción viable, y si pudieras elegir cualquier idioma, cuál sería?

+0

@disown: El GC no es tu único enemigo. El inicio JIT también puede introducir un pico de latencia (que fue visible en un Google E/S 2010 habla por cierto, donde el nuevo dispositivo Android JIT funcionaría más lento al principio que el que no es JIT, luego más rápido). Creo que puede interesarte http://javolution.org donde hay bastantes artículos interesantes vinculados. – SyntaxT3rr0r

+0

@Webinator: gracias por el enlace, examinándolo ahora ... –

Respuesta

1

El GC solo se utiliza para reclamar memoria de objetos descartados. Deseche muy pocos recursos y obtendrá GC muy pequeños y más cortos.

Puede usar muchos sockets, manejadores de archivos, identificadores de libs externos, pero ¿con qué rapidez los descarta?

Un GC completo está diseñado para eliminar la fragmentación. Hace esto copiando toda la memoria para que se use continuamente. Esta es la razón por la cual es costoso, por lo que debe minimizar estos si la latencia es importante para usted. Dicho esto, si sus GC completos tardan más de 100 ms, tiene un grave problema de rendimiento. No debería ser tan alto.

En mi humilde opinión, creo que debería ser capaz de desarrollar un sistema de control con una latencia que está por debajo de 10 ms, el 99% + del tiempo.

+0

Incluso si su programa es muy conservador con los recursos, ¿cómo se garantiza que las bibliotecas a las que llama no están agitando objetos a una velocidad épica? – user168715

+0

@ user168715: seleccionándolos con cuidado ... –

+0

No creo que podamos hacer mucha agrupación, los enchufes serán para diferentes clientes, así que vamos a estar construyendo y derribando bastante. Tal vez el almacenamiento en caché de las conexiones podría ser útil, y solo volver a iniciar cuando las conexiones expiren. Usted dice 'menos de 10 ms el 99% del tiempo'. Lo que me pregunto es si hay picos de 'peor caso' que son mucho más altos. No me refiero en teoría, pero si se ejecuta durante un par de meses, ¿cuál sería la latencia de su peor caso, y cómo se compara con lo que tendría en C++. Sé que es una pregunta realmente difícil de responder, solo estoy buscando consejos prácticos. –

2

Probablemente necesite una prueba de concepto si desea utilizar Java, le sugiero que escriba un prototipo simple y una prueba de esfuerzo, para examinar qué tiempo de latencia tiene bajo carga durante la recolección de basura. Luego revise los diferentes tipos de colectores, por ejemplo low pause collector.

El argumento RAII Realmente no entiendo, en C++ es IMHO más fácil crear fugas de memoria que en java.

+0

La memoria se filtra sí, pero RAII funciona también para otros recursos como conexiones DB y manejadores de archivos, donde en Jave lo único que se tiene es try/finally, que es definitivamente inferior a RAII (que AFAIK requiere objetos asignados por pila, por lo tanto imposible implementar en la JVM). –

+0

El colector de baja pausa aparentemente puede causar fragmentación de la memoria, según el artículo que he vinculado en mi pregunta. Sin embargo, no sé cuán severo es esto, y si C++ será mejor. RAII definitivamente ayuda a no perder recursos, por lo que estaba buscando un RAII lang. –

1

Me mantendría alejado de GC (sin duda como se implementa en cualquier JVM que he visto) en un entorno así. Siempre estarás golpeando tu cabeza contra la pared en el problema.

Sin embargo, solo quería señalar que el argumento de RAII parece muy débil: necesita revisiones de código y otro tipo de capacitación para garantizar que su equipo comprenda bien estos problemas.Es una muy mala razón para excluir un idioma que de otro modo sería apropiado, ya que cada idioma tiene errores que un programador inexperto/menos estelar puede perder.

Sentí en su lista que se estaba perdiendo C# (estoy pensando en Mono) donde tiene mucho más control cuando lo necesita. No sé si es apropiado para tu entorno, pero si incluyes VB en tu lista de idiomas, es un descuido obvio.

+0

La lista de lavandería solo constaba de idiomas que podían admitir RAII y tener devoluciones de llamada fuera del alcance. C# tiene 'usar', pero esto es solo azúcar sintáctico para probar ... por último, que también tienes en Java. No me refiero a que RAII sea una bala de plata, es solo una característica muy útil para ayudar a los programadores a no perder recursos. Me preocupa que el código sea más difícil de leer si no tenemos RAII, eso es todo. –

+0

@disown, estaba pensando más en que C# tiene la mayoría de las ventajas de Java (con la excepción de las librerías) con una integración más sencilla, y creo que 'using' es mucho más fácil de comprobar estáticamente para detectar el error al utilizar try /finalmente. Si su problema es la legibilidad, entonces 'using' también es más fácil de leer IMO. Sin embargo, en realidad no lo estoy perdonando, solo digo que parece que merece consideración. D y ADA pueden ser mejores opciones. – Yishai

Cuestiones relacionadas