我使用改造发送相当大的文件,偶尔会有OOM。方法:
@POST("/psm-service/model/{model}/video")
void sendVideo(@Header("X-Facebook-Access-Token") String token,
@Header("X-FB-Id") long fbId,
@Header("Content-Disposition") String contentDisposition,
@Path("model") long modelId,
@Body TypedOutput video,
Callback<Response> callback);
服务:
RestAdapter adapter = new RestAdapter.Builder()
.setClient(new OkClient(Certification.getClient(this)))
.setEndpoint(Api.ENDPOINT)
.setLogLevel(BuildConfig.DEBUG ? RestAdapter.LogLevel.BASIC : RestAdapter.LogLevel.NONE)
.build();
service = adapter.create(Api.ApiService.class);
客户端是具有自定义SSL的OkHttpClient。我的身体是一个TypedOutput,它使用android内容URI并设置长度,mimetype和文件名。
@Override
public void writeTo(OutputStream out) throws IOException {
Utils.copyStream(getContentResolver().openInputStream(uri), out);
}
public static void copyStream(InputStream input, OutputStream output)
throws IOException
{
byte[] buffer = new byte[1024]; // Adjust if you want
int bytesRead;
while ((bytesRead = input.read(buffer)) != -1)
{
output.write(buffer, 0, bytesRead);
}
}
根据我的理解,这应该以1KB的块发送我的50个MB文件。由于服务器的限制,我必须传递文件大小。我已经尝试完全关闭日志,但这并没有帮助。
在一个较大的文件中,OOM被抛入此方法。
java.lang.OutOfMemoryError: Failed to allocate a 120252388 byte allocation with 16777216 free bytes and 81MB until OOM
at java.lang.AbstractStringBuilder.enlargeBuffer(AbstractStringBuilder.java:95)
at java.lang.AbstractStringBuilder.append0(AbstractStringBuilder.java:146)
at java.lang.StringBuffer.append(StringBuffer.java:219)
at com.splunk.mint.network.io.OutputStreamMonitor.updateBody(OutputStreamMonitor.java:67)
at com.splunk.mint.network.io.OutputStreamMonitor.write(OutputStreamMonitor.java:58)
at okio.Okio$1.write(Okio.java:78)
at okio.AsyncTimeout$1.write(AsyncTimeout.java:155)
at okio.RealBufferedSink.emitCompleteSegments(RealBufferedSink.java:133)
at okio.RealBufferedSink.write(RealBufferedSink.java:45)
at com.squareup.okhttp.internal.http.HttpConnection$FixedLengthSink.write(HttpConnection.java:300)
at okio.RealBufferedSink.emitCompleteSegments(RealBufferedSink.java:133)
at okio.RealBufferedSink$1.write(RealBufferedSink.java:148)
at lt.segfoltas.common.util.Utils.copyStream(Utils.java:51)
at lt.segfoltas.psm_casting.net.FormUploaderService$TypedStream.writeTo(FormUploaderService.java:565)
at retrofit.client.OkClient$1.writeTo(OkClient.java:88)
at com.squareup.okhttp.Call.getResponse(Call.java:237)
at com.squareup.okhttp.Call.execute(Call.java:84)
at retrofit.client.OkClient.execute(OkClient.java:53)
at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:326)
at retrofit.RestAdapter$RestHandler.access$100(RestAdapter.java:220)
at retrofit.RestAdapter$RestHandler$2.obtainResponse(RestAdapter.java:278)
at retrofit.CallbackRunnable.run(CallbackRunnable.java:42)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at retrofit.Platform$Android$2$1.run(Platform.java:142)
at java.lang.Thread.run(Thread.java:818)
编辑:
我对我的堆栈跟踪中的bugsense方法持怀疑态度,所以我评论了Mint.initAndStartSession
,现在我的堆保持在48MB,而之前它已经达到了200MB。虽然这解决了我的问题,但我还是想继续使用bugsense。