2010-05-26 7 views
7

Bei meiner Arbeit haben wir kürzlich die Systemarchitektur für eine Steuerungsanwendung fertiggestellt, die eine maximale Latenz von ungefähr ein bis zwei Sekunden hat. Es wird auf kleinen ARM-On-Chip-Boxen verteilt, die über ein IP-LAN kommunizieren.~ 1s Latenzkontroll-App: Ist das für Java geeignet?

Wir erwarten zunächst, dass wir C oder C++ verwenden würden, da es sich um eine klassische Steuersystemsprache handelt. Nachdem wir besprochen haben, wie man die Anwendung implementiert, stellen wir fest, dass C++ eine recht begrenzte Anzahl von Bibliotheken hat, keine Introspektion aufweist und einige andere Eigenschaften aufweist, die die Entwicklung verlangsamen könnten. Mein Kollege schlug dann vor, dass Java für den Job geeignet sein könnte.

Ich habe wirklich Angst vor der Latenz eines GC für eine Control-App, und ich zögere auch, RAII zu löschen, da die App eine Menge externer Ressourcen (Sockets, Datei-Handles, Handles von extern) verwenden wird libs usw.).

Die Pro/con Liste ist zur Zeit wie folgt:

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 

Die Speicherfragmentierung mit parallelen GC erwähnt wurde in this AMD article

Ich würde gerne Java verwenden, wenn GC Latenz war kein Problem und wir könnte RAII bekommen. Deshalb habe ich mir auch andere Sprachen angesehen, die RAII haben und als gute Alternativen dienen könnten, und bisher habe ich festgestellt, dass D, Ada, VB, Perl, Python (C), PHP, Tcl und Lua etwas zu haben scheinen Art von Rückruf außerhalb des Bereichs. Meine spontane Reaktion, dass vielleicht D, Python und ADA für eine Control-App geeignet sein könnten. D und ADA sind meine Favoriten.

Also meine Frage ist: Haben Sie irgendwelche Empfehlungen zu diesem Thema? Ist Java eine praktikable Option, und wenn Sie irgendeine Sprache wählen könnten, was wäre es?

+0

@disown: Der GC ist nicht dein einziger Feind. Das JIT-Kick-in kann auch eine Latenz-Spitze mit sich bringen (was in einem Google I/O 2010 zu sehen war, wo das neue Android JIT-Gerät zuerst langsamer als das Nicht-JIT-Gerät war, dann schneller). Ich denke, dass Sie an http://javolution.org interessiert sein können, wo es ziemlich viele interessante Artikel verbindet. – SyntaxT3rr0r

+0

@Webinator: Danke für den Link, schauen Sie es sich jetzt an ... –

Antwort

1

Der GC wird nur zum Wiederherstellen von Speicher von verworfenen Objekten verwendet. Entsorgen Sie sehr wenig Ressourcen und Sie erhalten sehr kleine, kürzere GCs.

Sie könnten viele Sockets, Dateigriffe, Griffe von externen Bibliotheken verwenden, aber wie schnell verwerfen Sie sie?

Ein vollständiger GC wurde entwickelt, um die Fragmentierung zu entfernen. Dies geschieht durch Kopieren des gesamten Speichers, so dass er kontinuierlich verwendet wird. Deshalb ist es teuer, deshalb möchten Sie diese minimieren, wenn die Latenz für Sie wichtig ist. Das heißt, wenn Ihre vollständigen GCs mehr als 100 ms benötigen, haben Sie ein ernsthaftes Leistungsproblem. Es sollte nicht so hoch sein.

IMHO, ich short Sie sollten in der Lage sein, ein Kontrollsystem mit einer Latenz zu entwickeln, die gut unter 10 ms ist, 99% + der Zeit.

+0

Selbst wenn Ihr Programm mit Ressourcen sehr konservativ ist, wie garantieren Sie, dass die Bibliotheken, die Sie aufrufen, nicht durch Objekte mit epischer Geschwindigkeit durchwühlen? – user168715

+0

@ user168715: indem ich sie sorgfältig auswähle ... –

+0

Ich glaube nicht, dass wir viel Pooling machen können, Sockets werden für verschiedene Clients sein, also werden wir ziemlich viel aufbauen und abbauen. Vielleicht kann das Zwischenspeichern der Verbindungen helfen und erst wieder neu starten, wenn die Verbindung unterbrochen wird. Sie sagen 'unter 10ms 99% der Zeit'. Ich frage mich, ob es "Worst-Case" -Spitzen gibt, die viel höher sind. Ich meine nicht in der Theorie, aber wenn Sie für ein paar Monate laufen, was wäre Ihre Latenz im schlimmsten Fall, und wie vergleicht das mit dem, was Sie in C++ haben würden. Ich weiß, es ist eine wirklich schwierige Frage zu beantworten, ich bin nur auf der Suche nach praktischen Tipps. –

2

Wahrscheinlich brauchen Sie ein Konzept, wenn Sie Java verwenden möchten, würde ich vorschlagen, ein einfaches Prototy- und einen Stresstest zu schreiben, um zu untersuchen, welche Latenzzeit Sie unter hoher Last während der Speicherbereinigung haben. Dann überprüfe die verschiedenen Sammlertypen, z. low pause collector.

Das RAII Argument verstehe ich nicht wirklich, in C++ ist es IMHO einfacher, Speicherlecks als in Java zu erstellen.

+0

Speicher leckt ja, aber RAII funktioniert auch für andere Ressourcen wie DB-Verbindungen und Datei-Handles, wo in Jave das einzige, was Sie haben, ist/endgültig, die RAII definitiv unterlegen ist (die AFAIK erfordert Stack-allokierte Objekte, so unmöglich auf der JVM implementieren). –

+0

Der Low-Pause-Collector kann offenbar Speicherfragmentierung verursachen, wie in dem Artikel, den ich in meiner Frage verlinkt habe. Ich weiß nicht, wie schwer das ist und ob C++ besser wird. RAII hilft definitiv nicht, Ressourcen zu verlieren, weshalb ich nach einer RAII-Sprache suchte. –

1

Ich würde von GC (sicherlich wie in jeder JVM ich gesehen habe) in einer solchen Umgebung bleiben. Du wirst für immer den Kopf gegen das Problem schlagen.

Allerdings wollte ich nur darauf hinweisen, dass das RAII-Argument sehr schwach erscheint - Sie benötigen Code-Reviews und andere Schulungen, um sicherzustellen, dass solche Probleme von Ihrem Team gut verstanden werden.Es ist ein sehr schlechter Grund, eine Sprache, die sonst angemessen ist, auszuschließen, da jede Sprache, die ein unerfahrener/weniger als stellarer Programmierer verpassen kann.

Ich fühlte von Ihrer Liste, dass Sie C# fehlten (ich denke mit Mono), wo Sie viel mehr Kontrolle haben, wenn Sie es brauchen. Ich weiß nicht, ob es für Ihre Umgebung geeignet ist, aber wenn Sie VB auf Ihrer Wäscheliste von Sprachen aufführen, war das ein offensichtliches Versehen.

+0

Die Wäscheliste bestand nur aus Sprachen, die RAII unterstützen und Rückrufe außerhalb der Reichweite haben. C# hat 'using', aber das ist nur syntaktischer Zucker zum ausprobieren..finally, den Sie auch in Java haben. Ich meine nicht, dass RAII eine Wunderwaffe ist, es ist nur eine sehr nützliche Funktion, * Programmierern * zu helfen, keine Ressourcen zu verlieren. Ich mache mir Sorgen, dass der Code schwerer zu lesen sein wird, wenn wir keine RAII haben, das ist alles. –

+0

@disown, dachte ich mehr daran, dass C# die meisten Java-Vorteile (mit Ausnahme der libs) mit einfacherer Integration hat, und ich denke, dass 'using' viel einfacher ist, statisch nach dem Fehler zu suchen, um try zu verwenden /endlich. Wenn Ihr Problem Lesbarkeit ist, dann ist 'using' auch besser lesbar IMO. Ich spreche nicht wirklich dafür, nur zu sagen, dass es scheint, als ob es Überlegung verdient. D und ADA können in der Tat eine bessere Wahl sein. – Yishai