java.lang.OutOfMemory错误时尝试通过 Rest 调用获取文档



我正在使用以下代码行进行Web服务调用,但是对于较大的文件,我得到了OutOfMemoryError。

我无法增加堆大小,所以只是想知道代码是否有问题,或者是否有更有效的方法来实现此目的。

Client client = Client.create();
WebResource webResource = client.resource(url);
ClientResponse response = webResource.accept("application/json")
.get(ClientResponse.class);
if (response.getStatus() != 200) {
throw new RuntimeException("Failed : HTTP error code : "
+ response.getStatus());
}
String output = response.getEntity(String.class);
decodedBytes = Base64.decodeBase64(output.getBytes());

以下是错误日志:

The WebLogic Server encountered a critical failure
java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:3332)
at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:124)
at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:596)
at java.lang.StringBuilder.append(StringBuilder.java:190)
at com.sun.jersey.core.util.ReaderWriter.readFromAsString(ReaderWriter.java:172)
at com.sun.jersey.core.util.ReaderWriter.readFromAsString(ReaderWriter.java:157)
at com.sun.jersey.core.provider.AbstractMessageReaderWriterProvider.readFromAsString(AbstractMessageReaderWriterProvider.java:114)
at com.sun.jersey.core.impl.provider.entity.StringProvider.readFrom(StringProvider.java:73)
at com.sun.jersey.core.impl.provider.entity.StringProvider.readFrom(StringProvider.java:58)
at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:634)
at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:586)
at net.deldot.util.DocumentInfoFromProjectPortal.getDocument(Unknown Source)
at net.deldot.servlet.publicsite.command.ProjectDocumentCommand.execute(Unknown Source)
at net.deldot.servlet.CommandExecutorServlet.internalProcessHttpRequest(Unknown Source)
at net.deldot.servlet.CommandExecutorServlet.doGet(Unknown Source)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:286)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:260)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:137)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:350)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:247)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3679)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3649)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:326)
at weblogic.security.service.SecurityManager.runAsForUserCode(SecurityManager.java:197)
at weblogic.servlet.provider.WlsSecurityProvider.runAsForUserCode(WlsSecurityProvider.java:203)
at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:71)
at weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(WebAppServletContext.java:2433)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2281)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2259)
at weblogic.servlet.internal.ServletRequestImpl.runInternal(ServletRequestImpl.java:1691)
Reason: There is a panic condition in the server. The server is configured to exit on panic

此外,对于某些文件,我正在获取用于解码文件的 OOM。日志是

The WebLogic Server encountered a critical failure
java.lang.OutOfMemoryError: Java heap space
at java.lang.StringCoding.encode(StringCoding.java:350)
at java.lang.String.getBytes(String.java:941)
at org.apache.commons.codec.binary.StringUtils.getBytes(StringUtils.java:96)
at org.apache.commons.codec.binary.StringUtils.getBytesUtf8(StringUtils.java:235)
at org.apache.commons.codec.binary.BaseNCodec.decode(BaseNCodec.java:394)
at org.apache.commons.codec.binary.Base64.decodeBase64(Base64.java:692)
at net.deldot.util.DocumentInfoFromProject.getDocument(Unknown Source)
at net.deldot.servlet.publicsite.command.ProjectDocumentCommand.execute(Unknown Source)
at net.deldot.servlet.CommandExecutorServlet.internalProcessHttpRequest(Unknown Source)
at net.deldot.servlet.CommandExecutorServlet.doGet(Unknown Source)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:286)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:260)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:137)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:350)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:247)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3679)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3649)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:326)
at weblogic.security.service.SecurityManager.runAsForUserCode(SecurityManager.java:197)
at weblogic.servlet.provider.WlsSecurityProvider.runAsForUserCode(WlsSecurityProvider.java:203)
at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:71)
at weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(WebAppServletContext.java:2433)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2281)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2259)
at weblogic.servlet.internal.ServletRequestImpl.runInternal(ServletRequestImpl.java:1691)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1651)
at weblogic.servlet.provider.ContainerSupportProviderImpl$WlsRequestExecutor.run(ContainerSupportProviderImpl.java:270)
at weblogic.invocation.ComponentInvocationContextManager._runAs(ComponentInvocationContextManager.java:348)
at weblogic.invocation.ComponentInvocationContextManager.runAs(ComponentInvocationContextManager.java:333)
at weblogic.work.LivePartitionUtility.doRunWorkUnderContext(LivePartitionUtility.java:54)
Reason: There is a panic condition in the server. The server is configured to exit on panic

如果您不想解码内存中的所有内容(例如,因为您没有足够的内存(,请尝试使用面向流的方法。

例如,您可以尝试使用Base64.Decoder#wrap。

尝试(未经测试(:

Base64.Decoder decoder = Base64.getDecoder();
try (InputStream is = decoder.wrap(response.getEntity(InputStream .class))) {
//process stream
}

从那里,您可以将内容写入数据库流或响应流等,而无需一次将整个内容加载到内存中。

最新更新