Java 如何获得机器的直接内存?

Java 如何获得机器的直接内存?,java,memory,Java,Memory,我目前正在尝试获取服务器直接内存值并将其存储到数据库中,但我一直在获取0值,我的方法是否无法返回正确的500 MB值 我的方法是: import java.lang.management.BufferPoolMXBean; import java.lang.management.ManagementFactory; ... public int toGb(long valueInBytes) { return (int) (valueInBytes / (1024 * 1024 * 10

我目前正在尝试获取服务器直接内存值并将其存储到数据库中,但我一直在获取
0
值,我的方法是否无法返回正确的
500 MB

我的方法是:

import java.lang.management.BufferPoolMXBean;
import java.lang.management.ManagementFactory;
...
public int toGb(long valueInBytes) {
    return (int) (valueInBytes / (1024 * 1024 * 1024));
}

public int getMemoryDirect() {
    long memoryDirect = 0;
    List<BufferPoolMXBean> pools = ManagementFactory.getPlatformMXBeans(BufferPoolMXBean.class);
    for(BufferPoolMXBean pool : pools) {
        if(pool.getName().equals("direct")) {
            memoryDirect = pool.getTotalCapacity();
        }
    }
    return toGb(memoryDirect);
}
导入java.lang.management.BufferPoolMXBean;
导入java.lang.management.ManagementFactory;
...
公共int toGb(长值字节){
返回值(int)(值字节/(1024*1024*1024));
}
public int getMemoryDirect(){
长内存方向=0;
列表池=ManagementFactory.getPlatformMXBeans(BufferPoolMXBean.class);
for(BufferPoolMXBean池:池){
if(pool.getName().equals(“direct”)){
memoryDirect=pool.getTotalCapacity();
}
}
返回toGb(memoryDirect);
}
是否有其他方法检索此值

欢迎提供任何帮助:)

您这里的问题可能在于
toGb
方法。在Java中,整数除法是最常用的。这意味着,如果有500 MB的数据要由该方法返回(500*1024*1024),并打算将其作为整数GB值返回,则除以(1024*1024*1024),该值将始终返回0。您可以通过尝试返回浮点值(例如double或float)来解决此问题


或者,如果没有池的名称等于“direct”,则可能从未设置
memoryDirect
变量。在这种情况下,memoryDict也将始终为0。

我必须为
XX:MaxDirectMemorySize
值编写一个自定义解析器,基本上检查G/M/K/none(B)中指定的值是否正确,并进行相应的转换

对于本地测试,请创建
setenv.bat
文件,您可以在其中指定自定义参数-f.e.
set“CATALINA_OPTS=%CATALINA_OPTS%XX:MaxDirectMemorySize=100M”
它将获得这100M的doe参数

并确保在中的VM参数中手动添加此变量
窗口>显示视图>服务器>(所选服务器)>打开启动配置>(x)=参数

在顶部的控制台中,您应该能够找到由Catalina设置的
XX:MaxDirectMemorySize
参数:


是否有任何池名实际上等于“direct”?如果没有,您当然会返回0。如果正确的值是
500MB
,并且您将它放在GB中,那么它将是
0.5GB
。但是
toGb()
方法返回一个
int
,所以
(int)0.5=0
@Michael所以它看起来直接本身就是
0
@fififi是的,如果值小于
1000
它将始终继续
0
的int值,现在的问题是direct is
0
@lpkej您可以使用调试器查看是否输入
for
循环,以及是否输入
if
条件。它可以帮助您,好吧,所以我尝试只打印
memoryDirect
实际具有的值(不带
toGB
),它返回0。这是否意味着此方法将无法获取直接值。
pools
变量为空,因此您首先没有在循环中进行迭代,或者pools.getName()字符串的格式与您认为的格式不同。您可以调试pools.size()和pools.getName()字符串的输出,以检查哪种情况是这样。因此,在调试器中,pool
objName
null
它不会进入
if
语句并返回
memoryDirect
默认值
0
。我知道在服务器的
proc
目录中有一个
meminfo
文件,其中指定了直接值:DirectMap4k、DirectMap2M、DirectMap1G。你知道如何实现这些价值吗?不幸的是,我在mxbeans或ManagementFactory方面没有太多的经验,所以我无法克服这一点。然而,我确实发现了,这可能对你有帮助,也可能没有帮助。祝你好运有一段
sun.misc.VM.maxDirectMemory()
代码返回我需要的值,但它有警告
访问限制:“VM”类型不是API
,很遗憾,由于需要,我无法使用。希望这个链接能帮助其他人!