РЕДАКТИРОВАТЬ: я перешел на использование reader.readAsDataURL(file);
и сделал еще пару изменений.Смотрите здесь:
try {
let file: File = data.file;
let reader = new FileReader();
reader.onloadend = (e:any) => {
this.uploadMessage = 0
let document = {
"document_name": file.name,
"document": reader.result,
"document_filesize": file.size
}
this.myAPI.saveAttachment(document).subscribe(data => {
if (data && data.message){
this.uploadMessage = data.message;
}
if (this.uploadMessage == 100){
this.dialogRef.close();
}
})
}
reader.readAsDataURL(file);
}
Вышеуказанный подход сокращает потребление памяти до 1 ГБ, все еще выше, чем я ожидал, но управляемо.Однако, чтобы учесть изменение клиента, я обновил бэкэнд, ожидая строки base64, а не необработанного двоичного файла через byte[]
.Смотрите здесь:
@RequestMapping(value = "/saveAttachment", method = RequestMethod.POST)
public @ResponseBody ResponseEntity<Attachment> postSaveAttachment(@RequestBody Attachment data) {
ReviewAttachment returnVal = null;
HttpHeaders httpHeaders = new HttpHeaders();
try {
Decoder decoder = Base64.getDecoder();
byte[] decodedByte = decoder.decode(data.getdocument().split(",")[1]);
FileOutputStream fos = new FileOutputStream(docLoc);
fos.write(decodedByte);
fos.close();
returnVal = AttachmentRepo.save(data);
}
catch (Exception e) {
e.printStackTrace();
return new ResponseEntity<Attachment>(returnVal, httpHeaders, HttpStatus.NOT_ACCEPTABLE);
}
return new ResponseEntity<Attachment>(returnVal, httpHeaders, HttpStatus.OK);
}
Однако, похоже, я только что перенес проблему с памятью на серверную часть.Я уже пытался увеличить Xms / Xmx до 1024 м, но это не помогло.Я получаю это:
JVMDUMP013I Обработанное событие дампа "systhrow", подробно "java / lang / OutOfMemoryError".java / lang / OutOfMemoryError: пространство кучи Java в java / lang / ThreadGroup.uncaughtException (ThreadGroup.java:872) в java / lang / ThreadGroup.uncaughtException (ThreadGroup.java:866) в java / lang / Thread.uncaughtException (поток.java: 1332) Исключение в потоке «https-jsse-nio-8090-AsyncTimeout» java / lang / OutOfMemoryError: пространство кучи Java в java / lang / ThreadGroup.uncaughtException (ThreadGroup.java:872) в java / lang / ThreadGroup.uncaughtException(ThreadGroup.java:866) в java / lang / Thread.uncaughtException (Thread.java:1332)
java.lang.OutOfMemoryError: пространство кучи Java в com.fasterxml.jackson.core.util.TextBuffer.carr (TextBuffer.java:778) ~ [jackson-core-2.8.10.jar! /: 2.8.10] в com.fasterxml.jackson.core.util.TextBuffer.finishCurrentSegment (TextBuffer.java:632) ~ [джексон-core-2.8.10.jar! /: 2.8.10] на com.fasterxml.jackson.core.json.UTF8StreamJsonParser._finishString2 (UTF8StreamJsonParser.java:2493) ~ [jackson-core-2.8.10.jar! /:2.8.10] на com.fasterxml.jackson.core.json.UTF8StreamJsonParser._finishAndReturnString (UTF8StreamJsonParser.java:2469) ~ [jackson-core-2.8.10.jar! /: 2.8.10] в com.fasterxml.jackson.core.json.UTF8StreamJsonParser.getText (UTF8StreamJson315).[jackson-core-2.8.10.jar! /: 2.8.10] на com.fasterxml.jackson.databind.deser.std.StringDeserializer.deserialize (StringDeserializer.java:36) ~ [jackson-databind-2.8.10.jar! /: 2.8.10] at com.fasterxml.jackson.databind.deser.std.StringDeserializer.deserialize (StringDeserializer.java:11) ~ [jackson-databind-2.8.10.jar! /: 2.8.10] вcom.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize (SettableBeanProperty.java:504) ~ [jackson-databind-2.8.10.jar! /: 2.8.10] в com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet (MethodProperty.java:104) ~ [jackson-databind-2.8.10.jar! /: 2.8.10] в com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject (BeanDeserializer.java:35)~ [jackson-databind-2.8.10.jar! /: 2.8.10] на com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize (BeanDeserializer.java:148) ~ [jackson-databind-2.8.10.jar! /: 2.8.10] в com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose (ObjectMapper.java:3814) ~ [джексон-databind-2.8.10.jar! /: 2.8.10] at com.fasterxml.jackson.databind.ObjectMapper.readValue (ObjectMapper.java:2938) ~ [jackson-databind-2.8.10.jar! /: 2.8.10] at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType (AbstractJackson2HttpMessageConverter.java:235) ~ [spring-web-4.3.14.RELEASE.jar! /: 4.3.14.RELEASE]1015 *
Я сейчас просматриваю эту ошибку, но подумал, что я буду обновлять этот пост по мере продвижения.
ORIG:
Моя логика загрузки в Angular Client:
let file: File = data.file;
let reader = new FileReader();
let attachmentArr: any[] = new Array;
let arr;
reader.onload = (e:any) => {
arr = new Int8Array(e.target.result)
for (var i = 0; i < arr.length; i++) {
attachmentArr.push(arr[i]);
}
};
reader.onloadend = (e:any) => {
this.uploadMessage = 0
let document = {
"document_name": file.name,
"document": attachmentArr,
"document_filesize": attachmentArr.length
}
this.myAPI.saveAttachment(document).subscribe(data => {
if (data && data.message){
this.uploadMessage = data.message;
}
if (this.uploadMessage == 100){
this.dialogRef.close();
}
})
}
reader.readAsArrayBuffer(file)
}
Когда я пытаюсь загрузить файл размером около 200 МБ, Chrome предупреждает меня, что он остановил выполнение, чтобы предотвратить ошибку нехватки памяти.Firefox предупредит о длительном запуске скрипта, но если я позволю ему продолжить, загрузка в конечном итоге завершится успешно.Тем не менее, у меня есть 16 ГБ оперативной памяти.Пользователь этого приложения имеет 2 ГБ и получает ошибку нехватки памяти в любом браузере, и загрузка не удалась.
Что мне интересно, так это то, что загрузка файла размером 200 МБ приводит к потреблению памяти объемом в несколько ГБ.Я не думаю, что это имеет какое-либо отношение к Angular, только к FileReader в WebAPI.