java.lang.OutOfMemoryError:Java堆空间,stringBase64到BufferedImage

时间:2017-10-04 08:27:54

标签: java out-of-memory inputstream outputstream

我有方法在base64中将图像作为字符串获取并缩放(如果需要)并将其转换为BufferedImage然后在ByteArrayInputStream中,并且在我将此图像加载到Google云后,但我发现了即使我没有加载到goole云中,我也会获得OutOfMemory,所以我测试了我的方法uploadJpgFromBase64,而且我确实得到了OutOfMemory。

我的uploadJpgFromBase64:

    package com.myproject.model.utils.google;

import org.imgscalr.Scalr;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Base64;


public class Gcloud {

    public static String uploadJpgFromBase64(String path, String content, int width, int height) throws Exception {
        String imageDataBytes = content.substring(content.indexOf(",") + 1);
        byte[] decodedString = Base64.getDecoder().decode(imageDataBytes);
        BufferedImage image = bufferedImage(decodedString);
        int imgWidth = image.getWidth();
        int imgHeight = image.getHeight();
        if (imgWidth > width || imgHeight > height) {
            BufferedImage resize = Scalr.resize(image, width, height);
            BufferedImage newBufferedImage = new BufferedImage(resize.getWidth(), resize.getHeight(), BufferedImage.TYPE_INT_RGB);
            newBufferedImage.createGraphics().drawImage(resize, 0, 0, Color.WHITE, null);
            try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
                ImageIO.write(newBufferedImage, "jpg", os);
                resize.flush();
                newBufferedImage.flush();
                InputStream inputStream = new ByteArrayInputStream(os.toByteArray());
                inputStream.close();
                return "test";
            }
        } else {
            BufferedImage newBufferedImage = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_RGB);
            newBufferedImage.createGraphics().drawImage(image, 0, 0, Color.WHITE, null);
            try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
                ImageIO.write(newBufferedImage, "jpg", os);
                newBufferedImage.flush();
                InputStream inputStream = new ByteArrayInputStream(os.toByteArray());
                inputStream.close();
                return "test";
            }
        }
    }

    private static BufferedImage bufferedImage(byte[] decodedString) throws IOException {
        try (InputStream is = new ByteArrayInputStream(decodedString)) {
            return ImageIO.read(is);
        }
    }

}

和堆栈跟踪:

    [2017-10-04T11:17:26.865+0300] [glassfish 5.0] [INFO] [] [] [tid: _ThreadID=36 _ThreadName=Thread-8] [timeMillis: 1507105046865] [levelValue: 800] [[
  2017-10-04 11:17:26 [http-listener-2(1)] DEBUG o.s.web.servlet.DispatcherServlet - Could not complete request
org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.OutOfMemoryError: Java heap space
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:982)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:706)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:791)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1580)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:338)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:317)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at com.myproject.rest.filter.JwtAuthenticationTokenFilter.doFilterInternal(JwtAuthenticationTokenFilter.kt:54)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:250)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:256)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:652)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:591)
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:371)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:238)
    at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:463)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:168)
    at org.glassfish.grizzly.http.server.HttpHandler$1.run(HttpHandler.java:224)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:593)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:573)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.OutOfMemoryError: Java heap space
    at java.awt.image.DataBufferByte.<init>(DataBufferByte.java:92)
    at java.awt.image.ComponentSampleModel.createDataBuffer(ComponentSampleModel.java:445)
    at java.awt.image.Raster.createWritableRaster(Raster.java:941)
    at javax.imageio.ImageTypeSpecifier.createBufferedImage(ImageTypeSpecifier.java:1074)
    at javax.imageio.ImageReader.getDestination(ImageReader.java:2892)
    at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(JPEGImageReader.java:1082)
    at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.java:1050)
    at javax.imageio.ImageIO.read(ImageIO.java:1448)
    at javax.imageio.ImageIO.read(ImageIO.java:1352)
    at com.myproject.model.utils.google.Gcloud.bufferedImage(Gcloud.java:54)
    at com.myproject.model.utils.google.Gcloud.uploadJpgFromBase64(Gcloud.java:24)
    at com.myproject.model.impl.DishServiceImpl.uploadDishPhoto(DishServiceImpl.kt:51)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
    at com.sun.proxy.$Proxy410.uploadDishPhoto(Unknown Source)
    at com.myproject.rest.controllers.json.dish.DishController.uploadDishPhoto(DishController.kt:56)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)
]]

[2017-10-04T11:17:26.866+0300] [glassfish 5.0] [WARNING] [] [javax.enterprise.web] [tid: _ThreadID=36 _ThreadName=http-listener-2(1)] [timeMillis: 1507105046866] [levelValue: 900] [[
  StandardWrapperValve[dispatcher]: Servlet.service() for servlet dispatcher threw exception
java.lang.OutOfMemoryError: Java heap space
    at java.awt.image.DataBufferByte.<init>(DataBufferByte.java:92)
    at java.awt.image.ComponentSampleModel.createDataBuffer(ComponentSampleModel.java:445)
    at java.awt.image.Raster.createWritableRaster(Raster.java:941)
    at javax.imageio.ImageTypeSpecifier.createBufferedImage(ImageTypeSpecifier.java:1074)
    at javax.imageio.ImageReader.getDestination(ImageReader.java:2892)
    at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(JPEGImageReader.java:1082)
    at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.java:1050)
    at javax.imageio.ImageIO.read(ImageIO.java:1448)
    at javax.imageio.ImageIO.read(ImageIO.java:1352)
    at com.myproject.model.utils.google.Gcloud.bufferedImage(Gcloud.java:54)
    at com.myproject.model.utils.google.Gcloud.uploadJpgFromBase64(Gcloud.java:24)
    at com.myproject.model.impl.DishServiceImpl.uploadDishPhoto(DishServiceImpl.kt:51)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
    at com.sun.proxy.$Proxy410.uploadDishPhoto(Unknown Source)
    at com.myproject.rest.controllers.json.dish.DishController.uploadDishPhoto(DishController.kt:56)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)
]]

我正在使用: Glassfish 5.20 春天4.3.9.RELEASE java8

在我的本地机器中,服务器重启后,我只是通过rest api开始使用这个方法将图像加载为base64字符串,并在15-20调用之后(其中我传递了1-2张图像)每个3-5 MB)我得到OutOfMemory。

所以我假设uploadJpgFromBase64中的一个流还没有释放内存... mb,但为什么呢?

P.S。

at com.myproject.model.utils.google.Gcloud.bufferedImage(Gcloud.java:54) ==  return ImageIO.read(is); in bufferedImage method

0 个答案:

没有答案