当前位置: 首页 > 知识库问答 >
问题:

为什么unix和Java运行时显示的统计数据存在差异

朱建弼
2023-03-14

我的应用程序有一些内存问题,需要帮助理解这些统计数据。

Unix'top'显示了我进程的这些统计数据-

VSZ: 37.4g
RSS: 20.0g 

因此,这意味着20g目前已被替换为该流程并投入使用。

然而,当我使用Runtime类从应用程序中打印统计数据时,我得到了以下结果:

Runtime.totalMemory() : 9.8G
Runtime.freeMemory()  : 3.6G
Runtime.maxMemory()  : 14.3G

为什么[Runtime.totalMemory()-Runtime.freeMemory()]与RSS不匹配?这是进程当前正在使用的内存。这两个数字之间存在巨大差异。

此外,运行时是否将未使用的内存(runtime.freemory())返回给操作系统供其他进程使用?

请注意,我的应用程序运行在使用共享和复制缓存设置的点对点GemFire缓存系统中。我需要优化应用程序以减少内存占用。

共有1个答案

水麒
2023-03-14

运行时。totalMemory显示当前可用的内存。Java懒散地分配内存。

此外,运行时是否将未使用的内存(runtime.freemory())返回给操作系统供其他进程使用?

否。如果是Java分配的内存(totalMemory),它现在就在Java进程中。

RSS:20.0g 14.3G

如前所述,Java除了使用堆之外还使用内存。此外,Gemfire使用堆外内存(请检查此项)。尝试在VisualVM缓冲区监视器中查看它们。

你的基础架构(操作系统、虚拟机)是什么?

如果您不能使用标准工具,您可能应该使用JMX编写自己的可维护性代理(例如)

使现代化

根据doc,默认情况下,Gemfire使用JVM堆。

好的

对于一个只使用~10G堆内存的进程,为什么RSS总是显示20G。

如果你还问,我会提供更多细节。什么是java内存使用?

  • 堆内存(Xmx)

要查看默认值,可以运行:

 java -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal -version

要查看特定流程的选项,可以运行:

 jps -lvm

unix中是否有命令行工具来确定rest的用法?

对他们中的一些人来说是的。对他们中的一些人来说不是。

对于直接内存,您可以尝试sun.misc.SharedSecrets.getJavaNioAccess(). getDirectBufferPool(). getMemoryUSE()。

例如,使用cmd:

 jcmd <pid> VM.native_memory baseline

但这取决于运行设置(NativeMemoryTracking)。您可以在这里阅读如何启用本机内存跟踪。

在linux中,您还可以使用:

 pmap -x <pid>

总之,这可能无关紧要,因为你的任务是:

请注意,我的应用程序运行在使用共享和复制缓存设置的点对点GemFire缓存html" target="_blank">系统中。我需要优化应用程序以减少内存占用。

而且不能影响本机内存的使用。我想看看JMAPutil,它可以显示类直方图。您应该检查GemFire中的大数据,并查看那些对象,可能是存储在缓存中的数据,而这些数据不应该存在。我的意思是,在优化缓存的实践中,我检查对象和字段,看看哪些字段是真正频繁的,哪些不是。另一种方法是检查序列化机制和对象布局。

正如我提到的,您可以使用可维护性代理:

import com.sun.tools.attach.VirtualMachine;
import sun.tools.attach.HotSpotVirtualMachine;

import java.io.InputStream;

public class JMemoryMain {

    public static void main(String[] args) throws Exception {
        final int pid = JMemoryMainUtils.getPid(args);
        final HotSpotVirtualMachine vm = (HotSpotVirtualMachine) VirtualMachine.attach(String.valueOf(pid));
        final byte[] buffer = new byte[1024];
        try (InputStream is = vm.heapHisto()) {
            for (int read; (read = is.read(buffer)) > 0;) {
                System.out.write(buffer, 0, read);
            }
        }
        vm.detach();
    }

}

你需要tools.jarJDK在依赖关系中运行这个。它可以打印你类直方图太,但有时工作,当jmap不。此外,当你应该等待很多时间,而直方图计算,你可以使用VM. getSystemDicpedia(),只找到你的类。而且,这将是有用的,如果你不能启用NMT,因为开销。

 类似资料:
  • 应用程序服务计划和消费计划中运行的Azure函数的行为差异。为什么? 我正在运行WkHtmlToPdf.exe,作为应用服务计划(B1)中Azure函数的一部分。我想将此Azure函数移至消耗计划,但似乎失败了。 我追踪到阻塞点是WkHtmlToPdf。exe,通过使用Kudo控制台。 使用消费计划中的Azure函数,它只会以死锁结束,永远不会返回控制台。 有什么想法吗?

  • 问题内容: 我写了一段代码来了解运行时多态性… 实例变量受到编译时的约束,但是为什么这里的对象的向下转换没有意义?表示它是调用方法而不是方法? 问题答案: 让我们看看这里有什么: 可变的的, 引用类型 ; 一个实例创建表达式,产生一个对象类型,其中; 一个 向上转型表达式参考 ,向上转型上述表达式成型; 将3.的结果分配给变量。 阅读Java时,您必须牢记以下几点: 对象 的 类型 :对象永远不能

  • 您将自动执行著名的歌曲“墙上的99瓶XXX”。你将打印这首歌所有99个诗句的歌词。用循环!如果你不知道歌词,用谷歌查一下。 该方案应: a.如果他们不到21岁,或者他们喜欢苏打水,那么歌词是“墙上有99瓶苏打水” B.如果他们超过21岁,那么是“99瓶啤酒” 您必须使用WHILE循环,并且counter变量必须是print语句的一部分! 所以第一节是: 99瓶苏打水挂在墙上 墙上有98瓶苏打水 最

  • 应用程序运行良好...只是数据没有出现...我已经添加了sha用户电子邮件显示在登录后,在登录活动中我已经添加了 但是在实时数据库数据不显示以防万一…我也等了半个小时,尝试了所有的东西…网络也不错。数据库中的数据库规则的数据库图片 mainActivity.java//不能用于单个子级,即firebaseDatabase.getInstance().getReference().child(“aj

  • 问题内容: 我已经用Java构建了一个小守护进程,我想在Unix(例如Debian 5)下作为服务运行它。我读过有可能使用Java包装器,但是难道没有其他更容易实现的选项吗?我不能只使用Unix命令吗? 问题答案: 好吧,即使您退出外壳程序也要运行Java程序,以下是最简单的方法:

  • 我在开发我的应用程序。但是我遇到的问题是数据没有完全显示在DataGridView中。 谢谢你。Love.net