BufferedImage b1 = new …
使用完后:
b1 = null
这样,JVM 就会知道 b1 的内存可以回收了。
当 jvm 知道 b1 = null 的时候,需要等到 jvm 本身运行 System.gc() 的时候,才会真正对 b1 产生出的内存进行回收。
如果你需要强制 jvm 立即进行内存回收,这个时候,你就需要手工在
b1 = null;
System.gc();
代码中直接加上 gc() 的调用。
但是,需要注意的是 System.gc() 回收的是对整个系统可以回收的对象收集一次,而不会专门只回收 b1 的内存,所以,当 System.gc() 在回收的过程中,如果还没回收到 b1 的时候,你就会发现内存没有立即释放出来,但如果 System.gc() 在回收的过程中,第一个先回收了 b1 的话,你就会感觉到内存立即增大了。
所以,这个是系统底层的逻辑,你需要做好的就是设置 b1 = null。
另外,除了 b1 = null 这样的设置外,你还需要注意,如:
java.util.HashMap() list = new java.util.HashMap();
list.add(…);
比如在这个 list 里面增加了 1000 个对象进去 HashMap 里面,你在将 list = null 前,需要先 list.clear();
list = null;
即先 clear() 再 null,这样做的时候,在 list 里面生成的 1000 个对象就会与 list 同时可以被 jvm 回收了。
BufferedImage
是Image的一个子类,
BufferedImage
生成的图片在
内存
里有一个图像缓冲区,利用这个缓冲区我们可以很方便的操作这个图片,通常用来做图片修改操作如大小变换、图片变灰、设置图片透明或不透明等。
BufferedImage
bufferedImage
= ImageIO.read(new FileInputStream(filePath));
业务上有一个缩放图片的操作使用了
BufferedImage
,但是经常发现生成图片失败。查看日志显示OutOfMemoryError:
Java
heap space,
内存
溢出错误。通过获取
java
hprof来分析,发现大部分
内存
被
BufferedImage
占用。难道生成缩略图后,没有自动
释放
?
答案是的,当
释放
图片后,再没有发生过OutOfMemoryError。看看如下代码:
在使用Thumbnailator时出现了OOM
问题
,但是其使用方法只有一行代码,无法针对其内部使用的对象进行资源
释放
,所以使用原生的
Java
类库中ImageIO来处理图片。 关键有三个类:ImageIO、
BufferedImage
、Graphics
ImageIO类包含两个静态方法:read()和write(),通过这两个方法即可完成对位图文件的读写,调用...
是的,你是对的。
BufferedImage
对象本身并不占用系统资源,因此不需要手动
释放
。但是,如果你使用了ImageIO.write方法将
BufferedImage
对象写入文件,那么在写入完成后,你需要手动关闭输出流,以
释放
相应的系统资源。示例代码如下:
BufferedImage
image = new
BufferedImage
(width, height,
BufferedImage
.TYPE_INT_ARGB);
// 在这里对
BufferedImage
进行操作
File output = new File("output.png");
try (ImageOutputStream outputStream = ImageIO.createImageOutputStream(output)) {
ImageIO.write(image, "png", outputStream);
} catch (IOException e) {
e.printStackTrace();
在这个示例中,我们使用了try-with-resources语句,以确保在ImageOutputStream对象不再需要时,自动关闭输出流并
释放
相应的系统资源。