栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

上传文件导致OOM

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

上传文件导致OOM

背景:使用hutool工具进行文件上传。
直接上代码:

	
       cn.hutool
        hutool-all
        5.1.0
    
	import cn.hutool.http.HttpRequest;
	import java.io.File;
	import java.util.*;
	//……
	String urlString = "……/upload";
	Map paramMap = new HashMap<>();
	File file = new File("D:\soft\Anaconda3-2021.05-Windows-x86_64.exe");
	paramMap.put("file", file);
	HttpRequest.post(urlString).form(paramMap).timeout(60*1000).execute().body();

当文件比较大的时候,就引发了OOM异常。

经过查阅HttpRequest源码发现它有一个字段:blockSize(Chuncked块大小,0或小于0表示不设置Chuncked模式),最终是设置到java.net.HttpURLConnection的chunkLength字段中。

Chuncked模式,即分块传输模式,

因此设置该值大于0即可解决该OOM问题。

附测试demo:
pom.xml:



    4.0.0

    cn.sky
    mytest
    1.0-SNAPSHOT

    
        8
        8
    
    
        org.springframework.boot
        spring-boot-starter-parent
        2.1.3.RELEASE
    

    
        
            org.springframework.boot
            spring-boot-starter-web
            2.2.2.RELEASE
        
        
            cn.hutool
            hutool-all
            5.1.0
        
        
            com.konghq
            unirest-java
            3.11.12
        
        
            com.alibaba
            fastjson
            1.2.78
        
        
            com.squareup.okhttp3
            okhttp
            3.13.1
        
    

MyController:

package cn.sky.mytest.controller;

import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import kong.unirest.HttpResponse;
import kong.unirest.Unirest;
import okhttp3.*;
import okhttp3.RequestBody;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.*;

@RequestMapping("/myController")
@RestController
public class MyController {

    @PostMapping("/upload")
    public Object upload(@RequestParam(value = "file") MultipartFile file){
        System.out.println(file.getOriginalFilename()+":"+(file.getSize()/1024/1024)+"M");
        return "ok";
    }

    @GetMapping("/test")
    public Object test(int type) throws IOException {
        String urlString = "http://localhost:8080/myController/upload";
        Map paramMap = new HashMap<>();
        File file = new File("D:\soft\Anaconda3-2021.05-Windows-x86_64.exe");
        paramMap.put("file", file);
        if(type==1) {
            int blockSize = 1024*10;
            String body = HttpRequest.post(urlString)
                    
                    .setChunkedStreamingMode(blockSize)
                    .form(paramMap).timeout(60*1000).execute().body();
            System.out.println(body);
        }else if(type==2){
            String body = HttpRequest.post(urlString).form(paramMap).timeout(60*1000).execute().body();
            System.out.println(body);
        }else if(type==3){
            HttpResponse stringHttpResponse = Unirest.post(urlString).fields(paramMap).asString();
            System.out.println(stringHttpResponse.getStatus()+":"+stringHttpResponse.getBody());
        }else if(type==4){
            OkHttpClient client = new OkHttpClient().newBuilder()
                    .build();
            MediaType mediaType = MediaType.parse("text/plain");
            RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM)
                    .addFormDataPart("file",file.getName(),RequestBody.create(MediaType.parse("application/octet-stream"),file))
                    .build();
            Request request = new Request.Builder()
                    .url(urlString)
                    .method("POST", body)
                    .build();
            Response response = client.newCall(request).execute();
            System.out.println(JSON.toJSONString(response));
        }
        return "ok";
    }

}


application.properties:

server.port=8080
#需要设置这个,否则文件太大会上传失败
spring.servlet.multipart.max-file-size = 1073741824
spring.servlet.multipart.max-request-size = 1073741824

启动脚本(限制内存为100M):

mvn spring-boot:run -Dspring-boot.run.jvmArguments="-Xmx100M -Xms100M"

访问地址:http://localhost:8080/myController/test?type=
type可为1,2,3,4,堆内存使用情况如下(文件为477M):
type=1:

type=2:

type=3:


type=4:

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/353415.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号