一、问题背景
有一个创建图片的项目,每个图片都包含很多的文字,项目中需要生成海量的这类图片。在windows电脑上运行程序发现C盘的存储空间不断下降,直至为0。
二、问题定位
1、定位磁盘的问题文件
当C盘存储空间为0时,使用《全能王C盘清理大师》这个工具清理文件,发现C盘的Users/<用户名>/AppData/Local/Temp目录下产生了大量的"+~JF"开头的文件,每个文件大约4000kB左右。如下图所示:
2、定位问题代码段
在IDEA中单步调试,确认到产生该文件的代码为:Font.createFont()方法。
代码片段如下:
public static BufferedImage generateFontImage(String text, int width, int height, String fontTTFName,
float fontWeight, Color fontColor) {
//字体加载以及设置
Font rawFont = null;
Font font = null;
Resource fontResource = new ClassPathResource("fonts/" + fontTTFName + ".TTF");
InputStream inputStream = fontResource.getInputStream();
rawFont = Font.createFont(Font.TRUETYPE_FONT, inputStream);
font = rawFont.deriveFont(Font.PLAIN, fontWeight).deriveFont(AffineTransform.getShearInstance(-0.18, 0));
查看Font.createFont的源码,片段如下:
public static Font createFont(int fontFormat, InputStream fontStream)
throws java.awt.FontFormatException, java.io.IOException {
if (hasTempPermission()) {
return createFont0(fontFormat, fontStream, null);
}
查看createFont0的源码,片段如下:
可以看到Font.createFont()方法在使用时确实产生了“+~JF”开头的文件。
进一步分析,发现自己写的代码中,每次生成图片文字都会调用一次字体文件创建,所以导致产生了大量的“+~JF”开头的文件。
三、问题修复
因为字体文件数量有限,没必要每次使用时都加载一次,所以使用缓存技术保证项目运行时每个字体文件仅加载一次。
第1步,创建字体库的hashmap
第2步,使用时判断字体库是否已加载,已加载则直接使用,未加载则加载一次。