0

我有这样的代码:

public static class Obj {//Class within class
Long a;

}

private static final Map<String, Obj> map = new ConcurrentHashMap<>();

public static void main(String[] args)
{
    for(long l = 0;l<10000090L;l++)
    {
        Obj o = new Obj();
        o.a = l;
        map.put("asd", o);
        map.remove("asd");
    }
}

在我的 PC 上,我已在线程中添加了此代码 - 因此我可以轻松查看内存使用情况。我已经开始使用 Your Kit Java Profiler 对其进行分析。

我向 VM 添加了其他参数:-XX:+UseConcMarkSweepGC -XX:+UseTLAB -XX:+CMSIncrementalMode -XX:+CMSIncrementalPacing

我测试此程序的结果:循环前您的套件显示 - 用户 Par 服务空间 0 字节,用户 Par 伊甸园空间 12 mb,使用 CMS Old Gen 0 字节 战利品后您的套件显示 - 用户 Par 服务空间 8 KB,用户 Par伊甸园空间 38 mb,使用 CMS 老一代 0 字节 1,6 mb

然后我强制垃圾收集器,结果:您的工具包显示 - 用户 Par 服务空间 0 字节,用户 Par Eden 空间 1.4 mb,使用 CMS Old Gen 1.5 mb

因此,如果我正确读取此值,则 Obj 或“asd”将保留在内存中,直到完全垃圾收集器。有没有办法让这些对象被实时删除,而无需等待垃圾收集器检查程序中的每个对象是否都可以访问?

4

2 回答 2

2

垃圾收集器会在需要时加入,并且在大多数情况下,它会在最优化的时间加入。手动请求 GC 触发 usingSystem.gc()可能根本没有优势。

此外,你怎么知道“abj”是否会一直停留到完整的 gc。您的伊甸园一代已占用 38 mb 空间,而老一代则为 0 mb。在您的情况下,只有短暂的对象是预期的行为(通常小型 gc 应该可以工作,除非您以非常快的速度插入并且伊甸园很快被填满)

于 2013-10-31T17:49:23.503 回答
2

垃圾收集器是唯一从内存中删除对象的东西。您可以随时调用System.gc(),请求垃圾收集器早点运行,而不是晚点。但通常情况下,没有必要。在您的程序遇到内存问题之前,垃圾收集器将自行运行。

于 2013-10-31T17:29:07.587 回答