2013-08-04 8 views
7

Ich habe Streams oft verwendet, aber ich lese nie viel darüber, wie sie tatsächlich funktionieren. Ich weiß auch nicht viel über sie, außer dass ein Strom nur eine Metapher ist. Ein Stream repräsentiert nur eine Sequenz von Bytes. Ich weiß nicht viel darüber, wie sie tatsächlich funktionieren, ich denke, das Öffnen eines Dateistroms in Java mit dem Betriebssystem, die die Funktionalität haben, einen "Zeiger" auf einen Stream zu geben.Wie wirken sich Datenströme in Java auf den Speicherverbrauch aus?

Meine Frage ist im Grunde, wie Streams den Speicherverbrauch beeinflussen. Wenn Sie zum Beispiel einen Eingabestream haben und Sie beginnen, von ihm zu lesen, fangen Sie nur an, den Speicherverbrauch mit der Menge der gelesenen Bytes zu erhöhen? Wenn Sie einen Stream in Java öffnen, laden Sie nicht die gesamte Datei, bevor Sie mit dem Lesen beginnen. Wenn Sie von einem Stream lesen und direkt in einen anderen Stream schreiben, erhöhen Sie nur den Speicher mit der Menge an Bytes, die Sie lesen (und möglicherweise im Puffer haben)? Wenn Sie Bytes in einem Byte-Array in Java lesen, dann erhöhen Sie den Speicherverbrauch mit der Größe der Datei?

Kann wie eine seltsame Frage klingen, aber ich könnte eine Anleitung/Korrektur nach meinem Verständnis benötigen. Vielen Dank.

+0

Sie haben eine sehr gute Erklärung [http://www.ibm.com/developerworks/library/j-zerocopy/index.html] Null Kopie. Außerdem werden die Puffer und die Speichernutzung erläutert. –

Antwort

3

Es gibt fast kein Speicheraufwand nach dem Lesen aus der InputStream. Es gibt einen sehr geringen OS-Overhead zum Öffnen einer Datei und einen kleinen Overhead in der JVM für eine neue Objektzuordnung. Es kann auch ein kleiner Overhead sein, wenn Sie BufferedInputStream verwenden, was standardmäßig 8 KB ist.

Der Aufwand für das Schreiben hängt sehr davon ab, wo Sie schreiben. Wenn es ein ist, dann ist es dasselbe wie oben beschrieben. Wenn es ein ByteArrayOutputStream ist, dann ist es im besten Fall (2 * Streamlänge) Bytes und (3 * Streamlänge) Bytes im schlimmsten Fall. I.e. Um 10k Bytes von einem InputStream in ein Byte-Array zu kopieren, werden im schlimmsten Fall 30k Bytes zugewiesen.

Der Grund dafür ist, dass ByteArrayOutputStream Größe Wachstum 2 Mal, nachdem es Limit erreicht ist und es auch einen neuen Puffer zuweist, wenn Sie toByteArray() aufrufen.

5

Alle Antworten oben sind gute Antworten, aber ich glaube nicht, dass sie Ihre ursprüngliche Frage zum Speicherverbrauch beantworten.

In Java können Sie Streams auf verschiedene Arten betrachten. Zunächst haben Sie Raw-Streams, die den Stream der niedrigsten Stufe darstellen und mit dem zugrunde liegenden Betriebssystem (Datei, Netzwerk usw.) mit minimalem Speicheraufwand interagieren. Zweitens sind gepufferte Streams, die verwendet werden können, um einen rohen Stream zu umhüllen und etwas Pufferung hinzuzufügen und die Leistung signifikant zu verbessern. Stream-Pufferung fügt einen festen Speicher-Overhead für die Pufferung hinzu und kann von Ihrer Anwendung festgelegt werden. Nicht sicher, was der Standard ist, aber es ist wahrscheinlich etwas minimal wie 32K. Die dritte Art von Stream ist ein Speicher-Stream (dh ByteArrayInput/Ouput) Diese verwenden so viel Speicher, wie Sie auf sie schreiben, und wachsen nach Bedarf und entsorgen ihren Speicher nicht, bis die Referenzzählung auf Null geht (sie sind) nicht mehr verwendet). Diese Streams sind sehr nützlich, können aber offensichtlich viel Speicher verbrauchen.

Der letzte Typ ist wirklich kein Stream, sondern ist eine Klasse von I/O namens Readers, die Unterstützung bei der Datenkonvertierung zu und von einem Stream bieten, wie oben erwähnt wurde. Diese Streams arbeiten entweder mit einem rohen. gepufferter oder Speicher-Stream und verbraucht so viel Speicher wie der zugrunde liegende Stream, der verwendet wird.

Verwandte Themen