tomcat temp临时文件不清空,占用硬盘,jdk字体内存泄漏

JSP老旧项目迁移过来的代码,生成海报,会读取图片,读取字体文件,绘制图片,会生成大量临时文件,内存泄漏。
方案一,服务器定时删除temp临时文件夹
方案二,图片、字体改用静态类读取文件,并且释放相关资源文件。


导致原因

java 复制代码
package com.huida.train.utils;

import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;

@Component
public class ResourceUtil {
    // 使用volatile保证多线程环境下的可见性,防止指令重排
    private static volatile BufferedImage activityShareBannerImage;
    private static volatile Font sourceHanSansFont;
    private static volatile BufferedImage backgroundImage;
    private static volatile Font rdFont;

    /**
     * 方正小标宋字体
     */
    private static volatile Font fzxbsjwFont;

    /**
     * 方正黑体
     */
    private static volatile Font htFont;

    /**
     * 仿宋
     */
    private static volatile Font fsFont;

    private static volatile BufferedImage bottomTextImg;


    private ResourceUtil() {
        // 私有构造函数,防止外部实例化
    }
    public static BufferedImage getBottomTextImg() {
        if (bottomTextImg == null) {
            synchronized (ResourceUtil.class) {
                if (bottomTextImg == null) {
                    try {
                        ClassPathResource resource = new ClassPathResource("static/qr/bottomText.png");
                        bottomTextImg = ImageIO.read(resource.getInputStream());
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
        return bottomTextImg;
    }

    public static Font getFsFont() {
        if (fsFont == null) {
            synchronized (ResourceUtil.class) {
                if (fsFont == null) {
                    try {
                        ClassPathResource fsFontResource = new ClassPathResource("static/font/fs_gbk.TTF");
                        fsFont = Font.createFont(Font.TRUETYPE_FONT, fsFontResource.getInputStream());
                    } catch (IOException | FontFormatException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
        return fsFont;
    }
    public static Font getHtFont() {
        if (htFont == null) {
            synchronized (ResourceUtil.class) {
                if (htFont == null) {
                    try {
                        ClassPathResource fsFontResource = new ClassPathResource("static/font/ht.TTF");
                        htFont = Font.createFont(Font.TRUETYPE_FONT, fsFontResource.getInputStream());
                    } catch (IOException | FontFormatException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
        return htFont;
    }

    public static Font getFzxbsjwFont() {
        if (fzxbsjwFont == null) {
            synchronized (ResourceUtil.class) {
                if (fzxbsjwFont == null) {
                    try {
                        ClassPathResource fsFontResource = new ClassPathResource("static/font/FZXBSJW.TTF");
                        fzxbsjwFont = Font.createFont(Font.TRUETYPE_FONT, fsFontResource.getInputStream());
                    } catch (IOException | FontFormatException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
        return fzxbsjwFont;
    }
    public static Font getSimsunFont() {
        if (rdFont == null) {
            synchronized (ResourceUtil.class) {
                if (rdFont == null) {
                    try {
                        ClassPathResource fsFontResource = new ClassPathResource("static/font/simsun.ttf");
                        rdFont = Font.createFont(Font.TRUETYPE_FONT, fsFontResource.getInputStream());
                    } catch (IOException | FontFormatException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
        return rdFont;
    }

    public static BufferedImage getBackgroundImage() {
        if (backgroundImage == null) {
            synchronized (ResourceUtil.class) {
                if (backgroundImage == null) {
                    try {
                        ClassPathResource resource = new ClassPathResource("static/qr/backgroundImage.png");
                        backgroundImage = ImageIO.read(resource.getInputStream());
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
        return backgroundImage;
    }

    public static BufferedImage getActivityShareBannerImage() {
        if (activityShareBannerImage == null) {
            synchronized (ResourceUtil.class) {
                if (activityShareBannerImage == null) {
                    try {
                        ClassPathResource resource = new ClassPathResource("static/qr/activity_share_banner.png");
                        activityShareBannerImage = ImageIO.read(resource.getInputStream());
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
        return activityShareBannerImage;
    }

    public static Font getSourceHanSansFont() {
        if (sourceHanSansFont == null) {
            synchronized (ResourceUtil.class) {
                if (sourceHanSansFont == null) {
                    try {
                        ClassPathResource fsFontResource = new ClassPathResource("static/font/SourceHanSans-Regular.otf");
                        sourceHanSansFont = Font.createFont(Font.TRUETYPE_FONT, fsFontResource.getInputStream());
                    } catch (IOException | FontFormatException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
        return sourceHanSansFont;
    }
}
java 复制代码
 @Override
    public String getStrainingShareCode2(Map<String, String> map) throws IOException, FontFormatException {
        String trainingCourseId = map.get("trainingCourseId");
        TrainingCourse trainingCoursePo = trainingCourseMapper.select(trainingCourseId);
        if (trainingCoursePo == null) {
            throw new TipUserException("活动-培训已被删除或不可见");
        }
        BufferedImage activityShareBannerImage = ResourceUtil.getActivityShareBannerImage();
        // 开启画图
        Graphics2D graphics = activityShareBannerImage.createGraphics();
        //字体样式
        Font font = ResourceUtil.getSourceHanSansFont().deriveFont(Font.BOLD, 27);
        //字体颜色
        float[] color = Color.RGBtoHSB(58, 58, 58, null);
        graphics.setColor(Color.getHSBColor(color[0], color[1], color[2]));
        graphics.setFont(font);
        String address = "";
        //地点
        if (trainingCoursePo.getAddress().length() >= 16) {
            address = trainingCoursePo.getAddress().subSequence(0, 14) + "...";
        } else {
            address = trainingCoursePo.getAddress();
        }
        drawWrapString(graphics, address, 50, 220, activityShareBannerImage.getWidth() - 100, null, null);
        //时间
        drawWrapString(graphics, DateUtils.dateTime(trainingCoursePo.getStartTime()) + " ~ " + DateUtils.dateTime(trainingCoursePo.getEndTime()), 50, 275, activityShareBannerImage.getWidth() - 100, null, null);
        //报名人数
        Long enrollNum = trainingCoursePo.getEnrollNum();
        if (ObjectUtils.isNull(enrollNum)) {
            enrollNum = 0L;
        }
        drawWrapString(graphics, enrollNum.toString() + "人报名", 50, 330, activityShareBannerImage.getWidth() - 100, null, null);
//        String base64 = ImgUtil.toBase64DataUri(activityShareBannerImage, "png");
//        return base64;
        // 指定文件路径
        String filePath = HuiDaConfig.getTrainUploadPath() + "/shareCode/" + trainingCoursePo.getRecordId() + "/" + trainingCoursePo.getRecordId() + "_" + enrollNum + ".png";
        File outputfile = new File(filePath);
        if (!outputfile.exists()) {
            String deleteFilePath = HuiDaConfig.getTrainUploadPath() + "/shareCode/" + trainingCoursePo.getRecordId();
            File deleteFileFile = new File(deleteFilePath);
            FileUtils.deleteDirectory(deleteFileFile);
            File parentDir = outputfile.getParentFile();
            if (!parentDir.exists()) {
                parentDir.mkdirs();
            }
            ImageIO.write(activityShareBannerImage, "png", outputfile);
        }
        activityShareBannerImage.flush();
        graphics.dispose();
        return filePath;
    }
相关推荐
盖世英雄酱581367 分钟前
java 深度调试【第一章:堆栈分析】
java·后端
本就一无所有 何惧重新开始34 分钟前
Redis技术应用
java·数据库·spring boot·redis·后端·缓存
低音钢琴1 小时前
【SpringBoot从初学者到专家的成长11】Spring Boot中的application.properties与application.yml详解
java·spring boot·后端
蓝色汪洋1 小时前
string字符集
java·开发语言
卿言卿语1 小时前
CC1-二叉树的最小深度
java·数据结构·算法·leetcode·职场和发展
=>>漫反射=>>1 小时前
配置的前世今生:从逻辑中抽离,又与逻辑有限融合
java·设计规范
让我上个超影吧1 小时前
深入浅出 Java 中的 CompletableFuture:让异步编程变得简单
java·开发语言
好家伙VCC2 小时前
**发散创新:探索群体智能编程中的新境界**随着科技的飞速发展,群体智能逐渐成为编程领域的一大研究热点。本文将深入探讨群体智能的概念、优
java·python·科技
秉承初心2 小时前
Java 23种设计模式的详细解析
java·设计模式