as Hochladen der @Jersey-Servicedatei verursacht OutOfMemoryError

Ich entwickle einen Formularübermittlungsdienst mit Jersey 2.0. Das Formular enthält mehrereTex Felder und einDate Feld. Ich muss @ extrahierDate, Dateinam, Dateimedientyp und Datei Inhaltstyp und speichern Sie sie im Objektspeicher.

@Path("upload")
@Consumes({MediaType.MULTIPART_FORM_DATA})
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public class UploadService {
    @POST
    public BlobDo uploadFile(FormDataMultiPart uploadedBody) {
        String accountSid = uploadedBody.getField("account-sid").getValue();
        String apiToken = uploadedBody.getField("api-token").getValue();
        String checksum = uploadedBody.getField("checksum").getValue();

        FormDataBodyPart bodyPart = uploadedBody.getField("file");
        MySwiftObject obj = new MySwiftObject(bodyPart.getValueAs(InputStream.class));
        obj.setName(bodyPart.getContentDisposition().getFileName());
        obj.setContentType(bodyPart.getMediaType().toString());
        obj.setContentDisposition(bodyPart.getContentDisposition().toString());
   ...
}

pom.xml

<jersey.version>2.17</jersey.version>

<dependency>
    <groupId>org.glassfish.jersey.containers</groupId>
    <artifactId>jersey-container-servlet-core</artifactId>
</dependency>
<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-json-jackson</artifactId>
</dependency>
<dependency>
    <groupId>org.glassfish.jersey.test-framework.providers</groupId>
    <artifactId>jersey-test-framework-provider-inmemory</artifactId>
</dependency>
<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-multipart</artifactId>
</dependency>
<dependency>
    <groupId>org.glassfish.jersey.core</groupId>
    <artifactId>jersey-server</artifactId>
</dependency>
<dependency>
    <groupId>org.glassfish.jersey.ext</groupId>
    <artifactId>jersey-bean-validation</artifactId>
</dependency>

form Submission Request

POST /nbs/v2/upload HTTP/1.1
Host: 127.0.0.1:8080
Cache-Control: no-cache
Postman-Token: a4c1d4e9-5f71-2321-3870-e9cac0524f8d
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryA2Z9pPMA7y3da8BG

------WebKitFormBoundaryA2Z9pPMA7y3da8BG
Content-Disposition: form-data; name="account-sid"

Q45Ppm5ukvdqjTQ6eW0O5ztTXipwnjKQx1p6cf+fbCQ=
------WebKitFormBoundaryA2Z9pPMA7y3da8BG
Content-Disposition: form-data; name="api-token"

6397cd691909fdc14cef67dbc1dc2dc3
------WebKitFormBoundaryA2Z9pPMA7y3da8BG
Content-Disposition: form-data; name="file"; filename="screen_4_100155.jpg"
Content-Type: image/jpeg

......Exif..MM.*.............................b...........j
------WebKitFormBoundaryA2Z9pPMA7y3da8BG
Content-Disposition: form-data; name="checksum"

6a3381b1d16bded4a3dfc325a8bb800e
------WebKitFormBoundaryA2Z9pPMA7y3da8BG

JVM Heap-Größe

-Xmx=1024mb
Das Proble

Beim Hochladen einer ~ 50MB-Datei werden zwei temporäre Dateien mit ähnlichen MD5-Summen im Verzeichnis @ erstell/tmp/tomcat7-tomcat7-tmp mit dem NamenFileBackedOutputStream7949386530699987086.tmp undMIME8234229766850016150.tmp

Vor dem Hochladen ist der Server fertig, der eine Ausnahme auslöst

javax.servlet.ServletException: org.glassfish.jersey.server.ContainerException: java.lang.OutOfMemoryError: Java heap space
    org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:421)
    org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:386)
    org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:335)
    org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:222)

und löscht die Datei mit dem NamenMIME8234229766850016150.tmp verlässt aber den anderen. Und nicht gelöschteFileBackedOutputStream....tmp Dateien füllen den gesamten Speicherplatz auf der Festplatte.

Was ich getan hab

rhöhen Sie den Heap-Speicher auf 7 GB, aber es können keine ~ 200 MB-Dateien hochgeladen werde

Job auf dem Server ausführen, um alte temporäre Dateien zu löschen.

Erstellte Datei mit dem Namenjersey-multipart-config.properties und content

jersey.config.multipart.bufferThreshold = -1

Die DateiMIME[random numbers].tmp wird nicht mehr erstellt, aberFileBackedOutputStream[random number].tmp hängt immer noch auf der Festplatte, es sei denn, Tomcat wird neu gestartet.

Frag

Wie kann Jersey mit großen Dateien (möglicherweise 1 GB) umgehen, ohne temporäre Dateien auf meiner Festplatte zu belassen? Der beste Fall wäre, überhaupt keine Festplatte zu verwenden und kleine Teile durch den Speicher zu übertragen.

Warum bekomme ichheap overflow Wenn der Eingabestream mit Dateien gesichert ist?

Materialien, die ich leseDie abschließende Erklärung habe ich bisher gefunden.leseDieser Typ hat ein ähnliches Problem, aber auf der Client-Seite.lese Kann Lösung enthalten, konnte aber die Antwort nicht verstehen.lesePretty nah an meinem Problem, kann es aber nicht klären.lese bufferThreshold Idee wurde von hier übernommen.lese

Antworten auf die Frage(2)

Ihre Antwort auf die Frage