从Java跟踪本机内存使用情况?

10 浏览
0 Comments

从Java跟踪本机内存使用情况?

有没有办法从Java中记录本机内存使用情况,即直接记录本机内存或进程使用的总内存(例如,询问操作系统)?\n我想在用户的机器上在后台运行这个功能,因此NativeMemoryTracking命令行工具并不是最理想的选择。我已经记录了堆大小的可用/最大/总量。\n背景:我的软件的用户报告了一个异常(如下所示),我不知道为什么会出现这个异常。我的程序确实使用了SWIG的本机代码,但它只是一个简单的API,我不认为它有内存泄漏,并且在堆栈跟踪中也没有出现(或在错误之前立即运行)。我的日志显示在出现错误时有足够的堆空间可用。所以我真的不知道如何追踪这个问题。\n

java.lang.OutOfMemoryError: null
    at java.io.RandomAccessFile.writeBytes0(Native Method) ~[na:1.7.0_45]
    at java.io.RandomAccessFile.writeBytes(Unknown Source) ~[na:1.7.0_45]
    at java.io.RandomAccessFile.write(Unknown Source) ~[na:1.7.0_45]

\n该错误发生在Windows(7或10)中的webstart中,使用以下参数配置:\n


0
0 Comments

问题的出现原因:

在Java中,我们无法直接跟踪和监控本地内存的使用情况。Java运行时环境提供了一些方法来获取Java堆内存的使用情况,例如通过Runtime类的totalMemory()和freeMemory()方法来获取已分配和可用内存的大小,但这些方法不能直接获取本地内存的使用情况。

解决方法:

要跟踪和监控本地内存的使用情况,我们可以使用Java的本地接口(JNI)来调用操作系统提供的相关函数。通过JNI,我们可以调用C或C++代码来获取本地内存的使用情况。

下面是一个示例代码片段,展示了如何使用JNI来跟踪本地内存的使用情况:

import java.nio.ByteBuffer;
public class NativeMemoryTracker {
    static {
        System.loadLibrary("NativeMemoryTracker");
    }
    public static native long getNativeMemoryUsed();
    public static void main(String[] args) {
        long nativeMemoryUsed = getNativeMemoryUsed();
        System.out.println("Native Memory Used: " + nativeMemoryUsed + " bytes");
    }
}

上述代码中,我们通过System.loadLibrary()方法加载了一个名为"NativeMemoryTracker"的本地库。这个本地库包含了一个名为getNativeMemoryUsed()的本地方法,用于获取本地内存的使用情况。

在C或C++代码中,我们可以使用操作系统提供的函数来获取本地内存的使用情况。具体的实现细节可以根据操作系统的不同而有所差异。例如,在Linux系统上,我们可以使用getrusage()函数来获取进程的内存使用情况。

#include 
JNIEXPORT jlong JNICALL Java_NativeMemoryTracker_getNativeMemoryUsed(JNIEnv *env, jclass cls) {
    struct rusage usage;
    getrusage(RUSAGE_SELF, &usage);
    return (jlong)usage.ru_maxrss;
}

上述C代码中,我们使用了getrusage()函数来获取当前进程的内存使用情况,并返回了最大的常驻内存集(resident set size)的大小。

通过上述的方法,我们可以在Java程序中通过JNI来调用C或C++代码,从而获取本地内存的使用情况。这样我们就能够更全面地了解Java程序在运行过程中所使用的内存情况,包括Java堆内存和本地内存的使用情况。

0
0 Comments

问题出现的原因:我想跟踪Java程序的本机内存使用情况,但是JVM没有提供相应的方法。

解决方法:我最终使用了这段代码(链接为https://stackoverflow.com/a/14927379/319034),它向操作系统请求RSS和Peak内存使用情况。由于我已经设置了一个SWIG模块,所以对我来说添加这段代码非常简单。但是由于在测试过程中遇到了一个随机的malloc异常,我不确定是否要将它保留在代码中,因为它可能不是线程安全的。

我对JVM没有提供相应的方法感到非常惊讶。如果有人知道有没有其他方法,请告诉我。

0
0 Comments

问题的出现原因:想要追踪JVM在特定方法或代码行上的内存使用情况,但是Runtime API只能追踪堆上分配的内存,无法追踪堆外分配的native memory。

解决方法:参考stackoverflow上的一个帖子,链接为http://stackoverflow.com/questions/2756798。然而,该方法需要在部署时手动添加内存调试标志,不符合生产环境中被动追踪内存的要求。

0