Java GC 未收集某些对象

标签 java garbage-collection

我的申请存在问题,并且已经缩小了范围。我的内存里好像有一些未使用过的东西。

然而奇怪的是,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/

相关文章:

java - 通过 Java 中的 getRuntime() 运行我的程序时遇到问题

java - CrudRepository 不允许删除 @RequestMapping

java - 使用 javax.tools.JavaCompiler 在内存中完全编译代码

java - BigDecimal.floatValue 与 Float.valueOf

java - html 单选按钮添加到数据库

java - G1GC 非常高的 GC 计数和 CPU,非常频繁的 GC 会降低性能

rust - Rust 的内存管理与编译时垃圾收集有何不同?

Java List.clear() 与 List = null

c# - 垃圾收集器的替代品是什么?

java - 在垃圾收集中可关闭?