java - 使用 Jackson ObjectMapper 抛出 OutOfMemoryError
问题描述
我正在尝试从 AsyncTask 线程中的 ObjectMapper 获取 JSON 格式字符串,但我不断收到 OutOfMemoryError 并且在清单文件中已经添加了该行
清单文件:
android:largeHeap="true"
android:hardwareAccelerated="false"
在 doInBackground 中执行的 AsyncTask 方法:
String url = "/plano/fiscalizacao/fiscalizar";
Realm realm = Realm.getDefaultInstance();
Fiscalizacao fiscalizacao = RealmOperations.getFiscalizacaoById(realm, idFiscalizacao);
if (fiscalizacao == null)
return;
ObjectMapper mapper = new ObjectMapperProvider().createDefaultObjectMapper();
String json = mapper.writeValueAsString(fiscalizacao);
StringEntity entity = new StringEntity(json, "UTF-8");
//HttpEntity entity = new ByteArrayEntity(json.getBytes("UTF-8"));
HttpResponse response = WebServiceSupport.post(context, url, entity);
if (WebServiceSupport.validaStatus(response)) {
String str = EntityUtils.toString(response.getEntity(), "UTF-8");
}
Fiscalizacao 类:
private static final long serialVersionUID = 1L;
@Nullable
private Date dataFiscalizacao;
@Nullable
private PlanoFiscalizacaoProcesso plano;
@Nullable
private String relatorio;
@Nullable
private Reparticao reparticao;
@PrimaryKey
private Long selfId;
@Nullable
private SyncStatus status_sync;
private TipoGrauAproveitamento tipoGrauAproveitamento;
private TipoMedida tipoMedida;
@Nullable
private Date versionDate;
Stacktrace 到我遇到的问题:
08-22 14:04:12.623 22737-32404/exi.co.mz.sigit.fiscalizacao E/UncaughtException:
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:300)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.OutOfMemoryError: Failed to allocate a 524300 byte allocation with 277842 free bytes and 271KB until OOM
at com.fasterxml.jackson.core.util.TextBuffer._charArray(TextBuffer.java:716)
at com.fasterxml.jackson.core.util.TextBuffer.expand(TextBuffer.java:675)
at com.fasterxml.jackson.core.util.TextBuffer.append(TextBuffer.java:471)
at com.fasterxml.jackson.core.io.SegmentedStringWriter.write(SegmentedStringWriter.java:67)
at com.fasterxml.jackson.core.json.WriterBasedJsonGenerator.writeRaw(WriterBasedJsonGenerator.java:476)
at com.fasterxml.jackson.core.util.DefaultPrettyPrinter$Lf2SpacesIndenter.writeIndentation(DefaultPrettyPrinter.java:382)
at com.fasterxml.jackson.core.util.DefaultPrettyPrinter.writeEndObject(DefaultPrettyPrinter.java:247)
at com.fasterxml.jackson.core.json.WriterBasedJsonGenerator.writeEndObject(WriterBasedJsonGenerator.java:179)
at com.fasterxml.jackson.core.json.WriterBasedJsonGenerator.close(WriterBasedJsonGenerator.java:882)
at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:2727)
at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:2210)
at exi.co.mz.fiscalizacao.rest.ParcelaClient.setFiscalizacao(ParcelaClient.java:184)
at exi.co.mz.fiscalizacao.rest.ParcelaClient.doInBackground(ParcelaClient.java:239)
at exi.co.mz.fiscalizacao.rest.ParcelaClient.doInBackground(ParcelaClient.java:33)
at android.os.AsyncTask$2.call(AsyncTask.java:288)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
继续堆栈跟踪:
08-22 14:04:12.923 22737-32404/exi.co.mz.sigit.fiscalizacao E/AndroidRuntime:
FATAL EXCEPTION: AsyncTask #3
Process: exi.co.mz.sigit.fiscalizacao, PID: 22737
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:300)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
尝试遵循大量代码的标准:
Caused by: java.lang.OutOfMemoryError: Failed to allocate a 524300 byte allocation with 277842 free bytes and 271KB until OOM
at com.fasterxml.jackson.core.util.TextBuffer._charArray(TextBuffer.java:716)
at com.fasterxml.jackson.core.util.TextBuffer.expand(TextBuffer.java:675)
at com.fasterxml.jackson.core.util.TextBuffer.append(TextBuffer.java:471)
at com.fasterxml.jackson.core.io.SegmentedStringWriter.write(SegmentedStringWriter.java:67)
at com.fasterxml.jackson.core.json.WriterBasedJsonGenerator.writeRaw(WriterBasedJsonGenerator.java:476)
at com.fasterxml.jackson.core.util.DefaultPrettyPrinter$Lf2SpacesIndenter.writeIndentation(DefaultPrettyPrinter.java:382)
at com.fasterxml.jackson.core.util.DefaultPrettyPrinter.writeEndObject(DefaultPrettyPrinter.java:247)
at com.fasterxml.jackson.core.json.WriterBasedJsonGenerator.writeEndObject(WriterBasedJsonGenerator.java:179)
at com.fasterxml.jackson.core.json.WriterBasedJsonGenerator.close(WriterBasedJsonGenerator.java:882)
at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:2727)
at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:2210)
at exi.co.mz.fiscalizacao.rest.ParcelaClient.setFiscalizacao(ParcelaClient.java:184)
at exi.co.mz.fiscalizacao.rest.ParcelaClient.doInBackground(ParcelaClient.java:239)
at exi.co.mz.fiscalizacao.rest.ParcelaClient.doInBackground(ParcelaClient.java:33)
at android.os.AsyncTask$2.call(AsyncTask.java:288)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
解决方案
得到了解决方案
使用 Realm 时,需要使用 .copyFromRealm() 从领域数据库中提取对象
Realm realm = Realm.getDefaultInstance();
Fiscalizacao fiscalizacao = realm.copyFromRealm(RealmOperations.getFiscalizacaoById(realm, idFiscalizacao));
推荐阅读
- android - react-native run-android 命令抛出“java.net.ConnectException:连接超时”错误
- amazon-web-services - Lambda 使用 boto3 创建 EC2 机器
- vhdl - 如何在一个 FPGA 上实现多个独立的器件?
- python - 在用户指定的范围内打印 5 的复数的程序
- java - 为什么这个 mySQL 数据库没有连接到 Netbeans?
- r - 对具有系统名称的多个变量运行相同的函数(即,基于试验编号)
- javascript - 错误的错误信息打印在错误的位置
- android-studio - 在 Android Studio 中将过滤器应用于图像时遇到问题
- reactjs - 如何使用 mapDispatchToProps 和父组件将道具传递给组件?
- java - 从异步方法调用spring上下文中的bean方法真的是并发的吗?