获取Java中可用的RAM

4
我想在Java应用程序中获取系统可用RAM的数量,特别是在Linux上,但需要跨平台。 不是可用于JVM的内存量,而是实际可用的物理RAM。 不是空闲RAM,我指的是可用RAM。
我尝试使用OperatingSystemMXBean,但它只返回免费RAM:当然,问题是Linux将消耗免费RAM作为磁盘缓存以加快系统速度,将“免费”金额减少到几乎为零,即使内核随时会转储该缓存如果需要更多RAM,因此需要一个“可用”值。
因此,大约一周后,我的应用程序将开始抱怨我的系统几乎没有RAM,我看着它说“不,系统可能只有100MB的RAM可用,但它有3GB的磁盘缓存可以随时释放”。
即使“已使用”的内存也比空闲内存更有用。 我阅读的有关获取“已使用”RAM的每个教程都说要使用“总计- 免费”:这不是同一件事。 总数 - 已使用!=可用,但比“免费”更接近,并且可以提供更准确的跟踪。
我觉得我肯定错过了什么。“自由”RAM在大多数情况下并不是非常有用的指标; 每当有人说他们想要“自由”RAM时,他们几乎总是指“可用”,即应用程序可以使用多少RAM。 我相当确定它们在Windows上是相同的,但在*nix中,“空闲”和“可用”之间的区别非常重要,似乎是Oracle / Sun的一个重大疏忽。

操作系统向您承诺一定配额(也许是……)的虚拟内存,您通常可以查找语言环境当前分配了多少。系统范围内的“可用内存”不是有用的指标,因为它严格受操作系统控制,操作系统将始终将其用于某些可能是“进程内存”的目的。随着时间的推移,对该资源的各种需求会起伏不定,操作系统会相应地做出反应。但它会遵守对您的应用程序的承诺:在您的配额范围内(如果有的话),您将获得所请求的[虚拟]内存。 - Mike Robinson
https://crunchify.com/java-runtime-get-free-used-and-total-memory-in-java/ - BugsForBreakfast
我不是想获取JVM的内存量,而是想获取系统内存的总量。 - WizardStan
你为什么需要知道这个?你的程序不应该关心内存。要么程序有足够的内存,要么没有。你花在这上面的所有时间都是浪费时间,因为没有一个合适的Java程序在试图完成它们的实际目的时会尝试管理内存。 - Kayaman
我认为没有办法做到这一点,但正如@Kayaman所说,如果有这个要求,那么目的是什么呢? - BugsForBreakfast
显示剩余9条评论
1个回答

1
这段代码片段解决了问题。
public static long getAvailableMem()
{
    String osName = System.getProperty("os.name");
    if (osName.equals("Linux"))
    {
        try {
            BufferedReader memInfo = new BufferedReader(new FileReader("/proc/meminfo"));
            String line;
            while ((line = memInfo.readLine()) != null)
            {
                if (line.startsWith("MemAvailable: "))
                {
                    // Output is in KB which is close enough.
                    return java.lang.Long.parseLong(line.split("[^0-9]+")[1]) * 1024;
                }
            }
        } catch (IOException e)
        {
            e.printStackTrace();
        }
    // We can also add checks for freebsd and sunos which have different ways of getting available memory
    } else
    {
        OperatingSystemMXBean osBean = ManagementFactory.getOperatingSystemMXBean();
        com.sun.management.OperatingSystemMXBean sunOsBean = (com.sun.management.OperatingSystemMXBean)osBean;
        return sunOsBean.getFreePhysicalMemorySize();
    }
    return -1;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接