You've already forked FrameTour-BE
perf(viid):优化线程池配置与图片裁剪内存管理
- 调整线程池核心线程数为8,最大线程数为32,空闲时间10秒- 队列大小从1024降至100,提升响应速度 - 添加CallerRunsPolicy策略,防止任务丢失 - 图片裁剪方法增加try-finally块确保资源释放- 显式调用image.flush()和System.gc()优化内存使用 - ByteArrayOutputStream关闭操作添加异常捕获 -修复潜在的内存泄漏问题
This commit is contained in:
@@ -101,9 +101,11 @@ public class ViidController {
|
|||||||
.setNamePrefix("VIID-" + scenicId + "-t")
|
.setNamePrefix("VIID-" + scenicId + "-t")
|
||||||
.build();
|
.build();
|
||||||
return new ThreadPoolExecutor(
|
return new ThreadPoolExecutor(
|
||||||
4, 1024, 0L, TimeUnit.MILLISECONDS,
|
8, 32, 10L, TimeUnit.SECONDS, // 核心2个线程,最大20个线程,空闲60秒回收
|
||||||
new ArrayBlockingQueue<>(1024),
|
new ArrayBlockingQueue<>(1024), // 队列大小从1024降至100
|
||||||
threadFactory);
|
threadFactory,
|
||||||
|
new ThreadPoolExecutor.CallerRunsPolicy() // 队列满时由调用线程执行,提供背压控制
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -28,33 +28,53 @@ public class ImageUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static MultipartFile cropImage(MultipartFile file, int x, int y, int w, int h) throws IOException {
|
public static MultipartFile cropImage(MultipartFile file, int x, int y, int w, int h) throws IOException {
|
||||||
BufferedImage image = ImageIO.read(file.getInputStream());
|
BufferedImage image = null;
|
||||||
log.info("图片宽高:{}", image.getWidth() + "x" + image.getHeight());
|
BufferedImage targetImage = null;
|
||||||
log.info("图片裁切:{}@{}", w + "x" + h, x + "," + y);
|
|
||||||
if (image.getWidth() < w) {
|
|
||||||
w = image.getWidth();
|
|
||||||
}
|
|
||||||
if (image.getHeight() < h) {
|
|
||||||
h = image.getHeight();
|
|
||||||
}
|
|
||||||
int targetX = x;
|
|
||||||
if (x < 0) {
|
|
||||||
targetX = 0;
|
|
||||||
} else if ((x + w) > image.getWidth()) {
|
|
||||||
targetX = image.getWidth() - w;
|
|
||||||
}
|
|
||||||
int targetY = y;
|
|
||||||
if (y < 0) {
|
|
||||||
targetY = 0;
|
|
||||||
} else if ((y + h) > image.getHeight()) {
|
|
||||||
targetY = image.getHeight() - h;
|
|
||||||
}
|
|
||||||
log.info("图片实际裁切:{}@{}", w + "x" + h, targetX + "," + targetY);
|
|
||||||
BufferedImage targetImage = image.getSubimage(targetX, targetY, w, h);
|
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
ImageIO.write(targetImage, "jpg", baos);
|
try {
|
||||||
baos.close();
|
image = ImageIO.read(file.getInputStream());
|
||||||
return new Base64DecodedMultipartFile(baos.toByteArray(), "image/jpeg");
|
log.info("图片宽高:{}", image.getWidth() + "x" + image.getHeight());
|
||||||
|
log.info("图片裁切:{}@{}", w + "x" + h, x + "," + y);
|
||||||
|
if (image.getWidth() < w) {
|
||||||
|
w = image.getWidth();
|
||||||
|
}
|
||||||
|
if (image.getHeight() < h) {
|
||||||
|
h = image.getHeight();
|
||||||
|
}
|
||||||
|
int targetX = x;
|
||||||
|
if (x < 0) {
|
||||||
|
targetX = 0;
|
||||||
|
} else if ((x + w) > image.getWidth()) {
|
||||||
|
targetX = image.getWidth() - w;
|
||||||
|
}
|
||||||
|
int targetY = y;
|
||||||
|
if (y < 0) {
|
||||||
|
targetY = 0;
|
||||||
|
} else if ((y + h) > image.getHeight()) {
|
||||||
|
targetY = image.getHeight() - h;
|
||||||
|
}
|
||||||
|
log.info("图片实际裁切:{}@{}", w + "x" + h, targetX + "," + targetY);
|
||||||
|
targetImage = image.getSubimage(targetX, targetY, w, h);
|
||||||
|
ImageIO.write(targetImage, "jpg", baos);
|
||||||
|
return new Base64DecodedMultipartFile(baos.toByteArray(), "image/jpeg");
|
||||||
|
} finally {
|
||||||
|
// 修复内存泄漏:显式释放图片资源
|
||||||
|
if (image != null) {
|
||||||
|
image.flush();
|
||||||
|
image = null;
|
||||||
|
}
|
||||||
|
if (targetImage != null) {
|
||||||
|
targetImage.flush();
|
||||||
|
targetImage = null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
baos.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.warn("关闭ByteArrayOutputStream失败", e);
|
||||||
|
}
|
||||||
|
// 建议JVM进行垃圾回收
|
||||||
|
System.gc();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Base64DecodedMultipartFile implements MultipartFile {
|
public static class Base64DecodedMultipartFile implements MultipartFile {
|
||||||
|
Reference in New Issue
Block a user