1

我敢肯定我在这里犯了某种极其愚蠢的错误。我有这个代码:

private static String generateRAM()
{
    final long RAM_TOTAL = Runtime.getRuntime().totalMemory();
    final long RAM_FREE = Runtime.getRuntime().freeMemory();
    final long RAM_USED = RAM_TOTAL - RAM_FREE;
    final long RAM_TOTAL_MB = RAM_TOTAL / 8 / 1024;
    final long RAM_FREE_MB = RAM_FREE / 8 / 1024;
    final long RAM_USED_MB = RAM_USED / 8 / 1024;
    final double RAM_USED_PERCENTAGE = (RAM_USED / RAM_TOTAL) * 100;
    return RAM_TOTAL_MB + "MB TOTAL / " + RAM_FREE_MB + "MB FREE / " + RAM_USED_MB + "MB USED (" + RAM_USED_PERCENTAGE + "%)"; 
}

这将返回:

15440MB TOTAL / 11809MB FREE / 3630MB USED (0.0%)

这个百分比显然是不正确的。这是怎么发生的?据我所知,我所有的数学都是正确的。如果我将给定的数字打入计算器并自己找到百分比,我会得到 23.5,这是我的预期结果。

我确定我刚刚犯了一个可怕的错误,我会踢自己,有人可以启发我吗?

4

3 回答 3

3
final double RAM_USED_PERCENTAGE = (RAM_USED / RAM_TOTAL) * 100;

这是因为整数除法。将其中一种类型转换为加倍。

例子:

final double RAM_USED_PERCENTAGE = ((double)RAM_USED / RAM_TOTAL) * 100;

根据JLS 15.17.2。除法运算符 /

整数除法向 0 舍入。也就是说,在二进制数值提升(第 5.6.2 节)之后为整数的操作数 n 和 d 产生的商是一个整数值 q,其幅值尽可能大,同时满足 |d · q|。≤ |n|。此外,当 |n| 时 q 为正 ≥ |d| 并且 n 和 d 具有相同的符号,但是当 |n| 时 q 为负 ≥ |d| n 和 d 符号相反。

有一种特殊情况不满足此规则:如果被除数是其类型的最大可能量级的负整数,并且除数为-1,则发生整数溢出并且结果等于被除数。尽管溢出,在这种情况下不会抛出异常。另一方面,如果整数除法中除数的值为 0,则抛出 ArithmeticException。

于 2013-01-25T20:32:11.773 回答
1

更改此行

final double RAM_USED_PERCENTAGE = (RAM_USED / RAM_TOTAL) * 100;

final double RAM_USED_PERCENTAGE = ((RAM_USED * 1.0) / RAM_TOTAL) * 100;

这是因为 Java 将结果解释为long/long除法,因此结果将是一个long值,即 5 / 10 => 0。通过对任何操作数应用 1.0 的因子,编译器将执行double/long操作,这将产生一个double值。

于 2013-01-25T20:32:00.703 回答
1

您有 2 个错误。freeMemory()totalMemory()返回多个字节,因此要将其转换为 MB,您必须将其除以 1024(kB 和 MB)两次,然后除以 8。另外,您必须将 RAM_USED 转换为双精度数,以便将其计算为浮点数点操作:

private static String generateRAM()
{
    final long RAM_TOTAL = Runtime.getRuntime().totalMemory();
    final long RAM_FREE = Runtime.getRuntime().freeMemory();
    final long RAM_USED = RAM_TOTAL - RAM_FREE;
    final long RAM_TOTAL_MB = RAM_TOTAL / 1024 / 1024;
    final long RAM_FREE_MB = RAM_FREE  / 1024 / 1024;
    final long RAM_USED_MB = (double) RAM_USED / 1024 / 1024;
    final double RAM_USED_PERCENTAGE = ((double) RAM_USED / RAM_TOTAL) * 100;
    return RAM_TOTAL_MB + "MB TOTAL / " + RAM_FREE_MB + "MB FREE / " + RAM_USED_MB + "MB USED (" + RAM_USED_PERCENTAGE + "%)";
}

返回:

10MB TOTAL / 9MB FREE / 0MB USED (2.47130735892926%)
于 2013-01-25T20:36:17.703 回答