gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 02:24:35 24 4
gpt4 key购买 nike

我的应用程序遇到一些内存问题,需要帮助理解这些统计信息。

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

VSZ: 37.4g
RSS: 20.0g

因此,这意味着 20g 当前已换入进程并正在使用。

但是,当我使用运行时类从应用程序中打印统计信息时,我得到:

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

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

此外,运行时是否会将未使用的内存(Runtime.freeMemory())返还给操作系统以供其他进程使用?

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

最佳答案

Runtime.totalMemory 显示当前可用内存。 Java 延迟分配内存。

Also, does the runtime give back the unused memory (Runtime.freeMemory()) back to OS for use by other processes?

没有。如果Java分配了内存(totalMemory),它现在在java进程中。

RSS: 20.0g 14.3G

正如已经提到的,Java 除了堆之外还使用内存。Gemfire 还使用堆外内存 ( check this )。尝试在 VisualVM-Buffer Monitor 中查看它们。

您的基础设施(操作系统、虚拟机)是什么?

如果您无法使用标准工具,您可能应该使用 JMX 编写自己的可服务性代理 ( for example )

更新

As per doc, by default Gemfire uses JVM Heap.

好的

Why is RSS consistently showing 20G for a process that is using only ~10G of heap memory.

如果您仍然询问,我会提供更多详细信息。 java内存使用情况是怎样的?

  • 堆内存(Xmx);
  • 堆栈内存(每个线程都有自己的堆栈ThreadStackSizeVMThreadStackSize);
  • MaxPermSize 或 MaxMetaspaceSize(MaxPermGenSizeMaxMetaspaceSize);
  • 直接字节缓冲区(MaxDirectMemorySize);
  • 内存池(Par Eden 空间、Par Survivor 空间、CMS Old Gen、Metaspace/PermGen、代码缓存、压缩类空间 (CompressedClassSpaceSize));
  • 字符串表(所有 String.intern() 都将在其中,StringTableSize);
  • PerfDataMemorySize
  • MarkStackSize
  • 编译器线程堆栈大小
  • 常量池;
  • 我可能错过了 something ;

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

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

要查看适合您的特定进程的选项,您可以运行:

 jps -lvm

Is there an command line tool in unix to determine the rest usage?

对于其中一些人来说是的。对于其中一些人来说没有。

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

以cmd为例:

 jcmd <pid> VM.native_memory baseline

但这取决于运行设置(NativeMemoryTracking)。您可以阅读如何启用 native 内存跟踪 here .

在 Linux 中你还可以使用:

 pmap -x <pid>

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

Note that my applications are running in a peer to peer GemFire caching system set up with shared and replicated caches. I need to optimize the application to reduce memory footprint.

并且您不能影响 native 内存使用。我想看看jmap util,它可以显示类直方图。您应该检查 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();
}

}

您需要 JDK 中的依赖项中的 tools.jar 来运行它。它也可以打印类直方图,但有时可以工作,而 jmap 则不能。另外,当您需要等待很长时间时,在计算直方图时,您可以使用 VM.getSystemDictionary() 并仅查找您的类。而且,如果由于开销而无法启用 NMT,这将很有用。

关于java - 为什么unix和Java运行时显示的统计数据存在差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45964918/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com