【发布时间】:2015-06-07 01:47:31
【问题描述】:
对于我正在进行的一个项目,我的任务是创建一种将图像转换为非加密哈希的方法,以便可以轻松地将其与类似图像进行比较,但是我遇到了 JVM 开始处理的问题鲁莽地消耗内存,尽管 Java 监控和管理控制台没有报告内存消耗有任何增加。
当我第一次运行应用程序时,任务管理器会报告如下值: 然而,仅在大约 30 秒后,这些值就会增加一倍或三倍。
我使用 JMMC 创建了进程的转储,但它只报告了大约 1.3MB 的使用量:
对我来说最奇怪的部分是应用程序执行一个持续大约 15 秒的操作,然后等待 100 秒(调试),并且在线程休眠的 100 秒期间,使用的内存翻了一番。
这是我的两个课程:
ImageHashGenerator.java
package com.arkazex.srcbot;
import java.awt.Color;
import java.awt.Image;
import java.awt.image.BufferedImage;
public class ImageHashGenerator {
public static byte[] generateHash(Image image, int resolution) {
//Resize the image
Image rscaled = image.getScaledInstance(resolution, resolution, Image.SCALE_SMOOTH);
//Convert the scaled image into a buffered image
BufferedImage scaled = convert(rscaled);
//Create the hash array
byte[] hash = new byte[resolution*resolution*3];
//Variables
Color color;
int index = 0;
//Generate the hash
for(int x = 0; x < resolution; x++) {
for(int y = 0; y < resolution; y++) {
//Get the color
color = new Color(scaled.getRGB(x, y));
//Save the colors
hash[index++] = (byte) color.getRed();
hash[index++] = (byte) color.getGreen();
hash[index++] = (byte) color.getBlue();
}
}
//Return the generated hash
return hash;
}
//Convert Image to BufferedImage
private static BufferedImage convert(Image img) {
//Create a new bufferedImage
BufferedImage image = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_3BYTE_BGR);
//Get the graphics
image.getGraphics().drawImage(img, 0, 0, null);
//Return the image
return image;
}
}
Test.java
package com.arkazex.srcbot;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class Test {
public static void main(String[] args) throws IOException {
//Create a hash
byte[] hash = ImageHashGenerator.generateHash(ImageIO.read(new File("img1.JPG")), 8); //Memory grows to around 150MB here
System.out.println(new String(hash));
try{ Thread.sleep(100000); } catch(Exception e) {} //Memory grows to around 300MB here
}
}
编辑:该程序在几秒钟后停止增长到 300MB,原因不明。我没有更改代码中的任何内容,它只是停止了它。
【问题讨论】:
-
“Reckless”的意思是“我不知道它为什么要抢夺那段记忆”?除非它不断增长以填充最大空间,否则我不会将其称为“泄漏”本身。我倾向于 (a) 将其归结为 JVM 执行 JVM 所做的事情,或者 (b) 使用分析工具深入挖掘。
-
程序运行得怎么样?
-
@immibis 我在 Eclipse 中运行它,但即使我尝试将它作为导出的 jar 文件运行,它仍然存在过度消耗问题。
-
进行堆转储并运行 eclipse MAT
-
“我没有更改代码中的任何内容,它只是停止了它。” -- 嗯......它可能只是垃圾收集:-)
标签: java memory memory-management memory-leaks