- Springboot服务接收文件上传时的内存占用
文件是不会占用内存,springboot为避免文件太大导致内存溢出,一般是会将文件写入到磁盘上的临时文件中。
后端限制文件上传大小:
spring:
servlet:
multipart:
max-file-size: 2MB #单个文件上传最大值
max-request-size: 100MB #总文件上传最大值
前端限制上传文件大小(这里使用element-plus的上传组件):
<el-upload :before-upload="limitSize"/>
import {ElMessage} from "element-plus"
const limitSize = (file) => {
const size = file.size / 1024 /1024;
if (size > 2) {
ElMessage.error("上传文件大小不能超过2MB");
return false;
}
return true;
}
java使用MultipartFile接收到的文件然后存到磁盘固定位置是不需要消耗内存的,使用 MultipartFile.transferTo()方法本质是将文件从临时文件位置移到最终指定的位置。
public void uploadFile(@RequestParam MultipartFile file) {
File target = new File("E:/data/doucument/" + file.getOriginalFileName());
if (target.exists() || target.mkdirs()) {
file.transferTo(target);
}
}
- 获取磁盘文件并输出客户端内存消耗
读取文件:使用InputStream读取磁盘文件,这一过程不会将整个文件加载到内存。
缓冲区:InputStream会将数据读取到缓冲区,缓冲区大小可以自定义。
发送数据:然后逐块写入到HttpServletResponse的outputStream并输出到客户端。
示例:
try(ServletOutputStream outputStream = response.getOutputStream();
FileInputStream inputStream = new FileInputStream("E:\\data\\test.png")){
//这里使用的是org.apache.commons.compress.utils.IOUtils,查看源码可以看到默认
//的缓冲区大小为8024个字节,同时有一个负载方法可以自定义缓冲区大小
IOUtils.copy(inputStream,outputStream);
}catch(Exception e) {
throw new BusinessException("读取文件失败");
}
- mybatis查询mysql数据库内存消耗
主要取决于查询数据的大小和使用对象的消耗
如:查询5条数据,每条数据100个字节(字节根据存储数据类型进行计算),每条数据一个对象额外开销(存储对象的元数据信息)一般在十几字节,这里假设为20字节;那么总的内存消耗为:
(100 + 20)* 5 = 600B
600 / 1024 约等于 0.586KB
- java中对象额外开销
对象头:mark work 8字节存储对象哈希码、GC分代年龄、锁状态等标识;32位的系统中会存储 Class Metadata Address 4字节对象所属类元数据地址,而在64位中是用偏移量来代替;所以32位对象最小的额外开销是12字节,64位是8字节.
实例数据:每个字段根据数据类型计算大小
额外填充:为了保持对象字节为8的倍数额外填充的字节