2009-07-11 8 views
3

Gibt es eine Möglichkeit, ein Byte-Array in Java zu pinnen, so dass es nie bewegt/verdichtet wird?Wie kann ich ein Byte-Array in Java anheften?

Ich arbeite an einer Anwendung, die während der Laufzeit null GCs haben soll, und ich möchte primitive Byte-Arrays verwenden, die an einen Speicherbereich gemappt sind. Gibt es eine Möglichkeit, dies zu tun oder mich daran zu hacken?

+0

Kann ich die Frage stellen: Warum? Warum möchten Sie kein GC in Ihrer Anwendung und warum möchten Sie das Array gepinnt? – Mnementh

+0

Ich versuche, RDMA in meinen Prozess zu integrieren, und ich möchte die bestmögliche Leistung erzielen. Ich möchte keine GC in meiner Anwendung, weil meine Anwendung sehr latenzempfindlich ist, und es darf nie pausieren, nicht einmal für 3ms. Ich möchte Byte-Arrays gepinnt und nicht direkt Byte-Puffer, weil Byte-Array-Zugriff Leistung ist viel besser als Byte-Puffer. –

Antwort

5

Wirklich null Müllsammlungen? "Ja wirklich?"

Wenn ja, würde ich eine von zwei Optionen vorschlagen:

  1. Verwenden Sie ein real-time JVM. Es gibt Optionen für die Verwaltung von fast allem, was allgemeine Anwendungen von weichen zu harten Echtzeitsystemen unterscheidet.
  2. Denken Sie sehr ernsthaft darüber nach, nur viel mehr Speicher zuzuweisen, als während eines bestimmten Laufs benötigt wird. Dies ist keine ausgeklügelte Lösung, aber wenn Sie über genügend Arbeitsspeicher verfügen, versuchen Sie, Ihrem Kernspeicher 10 Mal mehr zuzuweisen, als Sie erwarten. Es könnte einfach funktionieren und, Sie müssen zugeben, RAM ist billiger als Software-Engineering-Arbeit.

EDIT viel später:

Es kam nur zu mir, dass Sie Ihre Byte-Array Zuweisung statisch in Betracht ziehen sollten. Das heißt, so etwas wie diese:

/** Byte arrays that you absolutely have to keep. */ 
public class KeepForever { 
    /** Note that I make no claims about thread safety in this simple example. */ 
    public static byte [] keepMe = new byte[100]; 
}; 

// Much later in example code .... 

/** This should always succeed. No worries about garbage collection. */ 
public void setMe(int index, byte newByte) { 
    // Admittedly, this defeats several principles of OOD but it makes 
    // the point about the syntax. 
    KeepForever.keepMe[index] = newByte; 
} 
+0

Wirklich null Müllsammlungen. Meine Anwendung weist alles beim Start zu und führt keine weiteren Zuweisungen durch. Aber ich glaube nicht, dass eine Zuteilung garantiert, dass die JVM keinen GC betreibt und meinen Haufen verdichtet, was mein Anliegen ist. Ich möchte nicht eine Echtzeit-JVM verwenden, weil ich hohe durchgehend und niedrige Latenz im Gegensatz zu einer konsistenten mittleren Latenz und durchschnittlichen Durchsatz wollen. –

+1

Die Vorbelegung des Arrays verhindert nicht, dass es während der Garbage Collection verschoben wird (vorausgesetzt, etwas anderes löst den GC aus). – finnw

0

Obwohl es nicht zu direkter Speicherzuordnung verwendet ist, ein Objekt, das nicht GC'd wird noch referenzierbarer ist. Alles, wo die Referenz live bleibt, sollte in Ordnung sein.

+0

Aber mit einem Generations-GC wird es in den Speicher verschoben. – Mnementh

6

Sie können einen ByteBuffer/allocateDirect() verwenden Dies erstellt einen Byte-Puffer, der im "c" -Feld ist und keinen Heap verwendet, so dass er nicht verschoben wird und effizient mit JNI-Aufrufen verwendet werden kann.

+0

Byte-Puffer haben eine schlechtere Leistung als Byte-Arrays, also versuche ich, sie zu vermeiden. –

+2

Wirklich? Und ich dachte, der ganze Sinn von ByteBuffer wäre es, die Performance zu verbessern (zumindest für bestimmte Operationen);) Entweder Sie benötigen diese Funktionalität oder nicht. –

+1

Peter hat Recht und direkte NIO-Puffer werden in zahlreichen Java-Bindungen verwendet, weil sie normalerweise nicht verschoben werden und für JNI-Aufrufe geeignet sind. – gouessej

Verwandte Themen