Java数学(运行时内存百分比)

Java数学(运行时内存百分比),java,math,runtime,percentage,Java,Math,Runtime,Percentage,我肯定我犯了一些非常愚蠢的错误。 我有这个密码: 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

我肯定我犯了一些非常愚蠢的错误。 我有这个密码:

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,这是我的预期结果

我肯定我刚刚犯了一个可怕的错误,我会为此自责的,有人能告诉我吗?

改变这句话

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

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

更改此行

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

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

final double RAM_USED_PERCENTAGE = (RAM_USED / RAM_TOTAL) * 100;
这是因为整数除法。将其中一种类型强制转换为双精度

例如:

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

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

有一种特殊情况不满足此规则:如果 股息是其最大可能大小的负整数 类型,且除数为-1,则发生整数溢出,并且 结果等于股息。尽管溢出,但也没有例外 在这种情况下抛出。另一方面,如果 整数除法为0,则引发算术异常

这是因为整数除法。将其中一种类型强制转换为双精度

例如:

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

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

有一种特殊情况不满足此规则:如果 股息是其最大可能大小的负整数 类型,且除数为-1,则发生整数溢出,并且 结果等于股息。尽管溢出,但也没有例外 在这种情况下抛出。另一方面,如果 整数除法为0,则引发算术异常


您有两个错误
freemory()
totalMemory()
返回字节数,因此要将其转换为MB,必须将其除以1024(kB和MB)两倍,然后再除以8。另外,您必须将使用的RAM_转换为double,以便将其作为浮点运算进行计算:

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%)

您有两个错误
freemory()
totalMemory()
返回字节数,因此要将其转换为MB,必须将其除以1024(kB和MB)两倍,然后再除以8。另外,您必须将使用的RAM_转换为double,以便将其作为浮点运算进行计算:

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%)

谢谢真的很有帮助。我会尽快接受这个答案,让我回答。:)谢谢真的很有帮助。我会尽快接受这个答案,让我回答。:)没有注意到,我最初是用KB显示的。我更改了变量名和文本,但没有更改实际的数学。谢谢。因为那是真的。我不认为OP使用的是16GB内存机器:15440MB总容量令人惊讶的是,我没有你为什么要除以8?字节不是位。@FrankPavageau你说得对,我把字节和位弄混了:)我相应地更新了代码。没有注意到,我最初是用KB显示的。我更改了变量名和文本,但没有更改实际的数学。谢谢。因为那是真的。我不认为OP使用的是16GB内存机器:15440MB总容量令人惊讶的是,我没有你为什么要除以8?字节不是位。@FrankPavageau你说得对,我把字节和位弄混了:)我相应地更新了代码。