Ausgabestrom OutOfMemoryError beim senden von HTTP
Ich versuche zu veröffentlichen, ein großes video - /Bild-Datei aus dem lokalen Dateisystem zu einem http-Pfad, sondern ich Laufe in ein " out of memory Fehler nach einiger Zeit...
hier ist der code
public boolean publishFile(URI publishTo, String localPath) throws Exception {
InputStream istream = null;
OutputStream ostream = null;
boolean isPublishSuccess = false;
URL url = makeURL(publishTo.getHost(), this.port, publishTo.getPath());
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
if (conn != null) {
try {
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestMethod("PUT");
istream = new FileInputStream(localPath);
ostream = conn.getOutputStream();
int n;
byte[] buf = new byte[4096];
while ((n = istream.read(buf, 0, buf.length)) > 0) {
ostream.write(buf, 0, n); //<--- ERROR happens on this line.......???
}
int rc = conn.getResponseCode();
if (rc == 201) {
isPublishSuccess = true;
}
} catch (Exception ex) {
log.error(ex);
} finally {
if (ostream != null) {
ostream.close();
}
if (istream != null) {
istream.close();
}
}
}
return isPublishSuccess;
}
Hier ist der Fehler, ich bin immer...
Exception in thread "Thread-8773" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:2786)
at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:94)
at sun.net.www.http.PosterOutputStream.write(PosterOutputStream.java:61)
at com.test.HTTPClient.publishFile(HTTPClient.java:110)
at com.test.HttpFileTransport.put(HttpFileTransport.java:97)
Einige (einschließlich mich) betrachtet ist es unhöflich zu crosspost: forums.sun.com/thread.jspa?threadID=5424210 vor Allem, wenn Sie nicht einmal schweigen von der Tatsache.
Bitte nehmen Sie nicht Anstoß an der edit-wo ich kritisierte deinen code. Es ist besser als der Durchschnitt, hat aber Raum für Verbesserungen. Alle nicht-trivialen code funktioniert. Und es ist einfach zu versauen, exception-handling: ich bekam einen wohlverdienten -1 eine Woche oder so vor, wenn ich gerade eingegeben haben, in ein Beispiel-try/catch/finally, ohne dass mein compiler überprüfen.
Bitte nehmen Sie nicht Anstoß an der edit-wo ich kritisierte deinen code. Es ist besser als der Durchschnitt, hat aber Raum für Verbesserungen. Alle nicht-trivialen code funktioniert. Und es ist einfach zu versauen, exception-handling: ich bekam einen wohlverdienten -1 eine Woche oder so vor, wenn ich gerade eingegeben haben, in ein Beispiel-try/catch/finally, ohne dass mein compiler überprüfen.
InformationsquelleAutor ashchawla | 2010-01-17
Du musst angemeldet sein, um einen Kommentar abzugeben.
Den
HttpUrlConnection
ist die Pufferung der Daten, so dass Sie können dieContent-Length
header (pro HTTP-Spezifikationen).Einer alternative, wenn Ihr Ziel-server es unterstützt, ist die Verwendung von "chunked" überträgt. Dieser Puffer wird nur ein kleiner Teil der Daten zu einer Zeit. Aber nicht alle Dienste unterstützen (Amazon S3 zum Beispiel nicht).
Andere alternative (und imo besser), ist die Verwendung Jakarta HttpClient. Sie können die "Person" in einer Anfrage aus einer Datei, und die Verbindung code-set-request-Header entsprechend.
Edit: nos kommentierte, dass die OP nennen könnte
HttpURLConnection.setFixedLengthStreamingMode(long length)
. Ich hatte keine Ahnung von dieser Methode; es wurde Hinzugefügt, 1.5, und ich habe nicht verwendet diese Klasse seitdem.Aber ich noch vorschlagen, mit Jakarta HttpClient, aus dem einfachen Grund, dass es reduziert die Menge des Codes, den der OP hat, Sie zu pflegen. Code, boilerplate, aber dennoch das Potenzial für Fehler:
finally
block, und wieder, Glückwunsch dazu. Außer, dass entweder derclose()
Anrufe werfen könnteIOException
, halten die anderen von der Ausführung. Und die Methode als ganzes wirftException
, so dass der compiler ist nicht zu helfen, fangen ähnliche Fehler.Selbst wenn der OP geschrieben hatte, dieser code perfekt, und überarbeitete es, in die Methoden ähnlich wie in Jakarta-Commons-IO, er/Sie sollte das nicht tun. Dieser code wurde geschrieben und getestet von anderen. Ich weiß, dass es eine Verschwendung von meine Zeit neu zu schreiben, und vermute, dass es ist eine Verschwendung, die OP-Zeit als gut.
nos ist richtig. Es gibt absolut keine verwenden müssen, eine in Abschnitte aufgeteilte anfordern oder verwenden Sie 3rd-party-Bibliotheken. Rufen Sie einfach setFixedLengthStreamingMode mit der Länge der Datei auf die HttpURLConnection vor dem anschließen und getOutputStream liefert eine nicht-Pufferung eine direkte wrapper, um die socket - Ausgabestrom.
Ich nehme an, Sie sind die person, die downvoted mich und alle anderen, die geantwortet haben. Und während Ihre Kommentare sind wertvoll, es wäre besser gewesen, konstruktiv zu posten als Antwort.
Du hast Recht. Sie hatte nichts konstruktives hinzu zu fügen. Nun, was auch immer Sie glücklich macht. Ich bin ganz beeindruckt von deinen upvote:downvote-Verhältnis, btw.
bearbeitet die post mit etwas mehr Erklärung, dass hoffentlich gibt Sie ein Verständnis dafür, warum ein "one-line-modification" (es müssten eigentlich zwei sein) ist "definitiv nicht die einfachste Lösung."
InformationsquelleAutor kdgregory
Und für die Zwischenspeicherung der Sie decken könnte Ihre streams in die BufferedOutputStream und BufferedInputStream
Gutes Beispiel chunked Upload könnten Sie dort finden: gdata-java-client
InformationsquelleAutor Alexandr
Das problem ist, dass die HttpURLConnection-Klasse ist mit einem byte-array zum speichern Ihrer Daten. Vermutlich das video, das Sie treibt, ist die Einnahme von mehr Speicher als zur Verfügung. Sie haben ein paar Optionen hier:
Erhöhen Sie den Speicher für Ihre Anwendung. Sie können-Xmx1024m-option zu geben, die 1 GB Speicher für Ihre Anwendung. Dadurch erhöht sich die Menge Daten, die Sie im Speicher speichern.
Wenn Sie noch nicht genuegend Arbeitsspeicher ausführen, möchten Sie vielleicht zu prüfen, versuchen eine andere Bibliothek, um die push-video -, speichert die Daten nicht alle im Speicher auf einmal. Das Apache-Commons-HttpClient hat eine solche Funktion. Besuchen Sie diese Website für weitere Informationen: http://hc.apache.org/httpclient-3.x/features.html. Siehe diesen Abschnitt für multi-part form-upload von großen Dateien: http://hc.apache.org/httpclient-3.x/methods/multipartpost.html
InformationsquelleAutor Chris Dail
Für alles andere als grundlegende GET-Operationen, die gebaut-in
java.net
HTTP Zeug ist nicht sehr gut. Mit Apache-Commons-HttpClient empfohlen. Es lässt Sie viel mehr tun, intuitive Sachen wie diese:ersetzt eine Menge von Ihr boiler-plate-code.
InformationsquelleAutor skaffman
HttpsURLConnection#setChunkedStreamingMode(1024 * 1024 * 10); //10MB Stück
Dadurch wird sichergestellt, dass eine Datei (beliebiger Größe) gestreamt wird über eine https-Verbindung ohne interne Pufferung. Dies sollte verwendet werden, wenn die Größe der Datei oder die Länge des Inhalts ist unbekannt.
InformationsquelleAutor Piyush Chordia
Dein problem ist, dass Sie versuchen zu lösen X video bytes in X/N bytes RAM, wenn N > 1.
Müssen Sie entweder zu Lesen, das video in einem kleineren Puffer und schreibt Sie heraus, wie Sie gehen oder stellen Sie die Datei zu verkleinern, oder vergrößern Sie den verfügbaren Speicher, um Ihren Prozess.
Überprüfen Sie Ihre heap-Größe. Sie können -Xmx zu erhöhen, wenn Sie genommen haben, der Standard.
InformationsquelleAutor duffymo