我的申请存在问题,并且已经缩小了范围。我的内存里好像有一些未使用过的东西。
然而奇怪的是,GC 不会收集它们(即使程序基本上处于空闲状态,即没有 Activity 的处理线程),但当我在 Netbeans IDE 的 Profiler 中按“收集垃圾”时,它确实会收集。
我找到了导致暂时使用大量内存的代码:
private Integer getWhiteLines(BufferedImage image) {
Map<Integer, List<Color>> heightColors = new HashMap<>();
for (int h = 0; h < image.getHeight(); h++) {
List<Color> colors = new ArrayList<>();
for (int w = 0; w < image.getWidth(); w++) {
int colorRGBA = image.getRGB(w, h);
Color color = new Color(colorRGBA, true);
colors.add(color);
}
heightColors.put(h, colors);
}
Integer whiteLines = 0;
for (Map.Entry<Integer, List<Color>> entry : heightColors.entrySet()) {
Color avgColor = avgColor(entry.getValue());
if (isWhite(avgColor)) {
whiteLines++;
}
}
return whiteLines;
}
它列出了图像(以前是 PDF 文件)中每个像素的颜色。
这个问题也相当大,例如在某些 PDF 上,Color
对象会占用 14MB 内存。
为什么会发生这种行为以及我该如何解决它?
最佳答案
只有当您需要内存分配并且您的虚拟机没有足够的资源时,GC 才不会强制收集内存。您可以通过以下方式减少占用空间:
private Integer getWhiteLines(BufferedImage image) {
Integer whiteLines = 0;
for (int h = 0; h < image.getHeight(); h++) {
List<Color> colors = new ArrayList<>();
for (int w = 0; w < image.getWidth(); w++) {
int colorRGBA = image.getRGB(w, h);
Color color = new Color(colorRGBA, true);
colors.add(color);
}
Color avgColor = avgColor(colors);
if (isWhite(avgColor)) {
whiteLines++;
}
}
return whiteLines;
}
关于Java GC 未收集某些对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19360109/