微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么以及如何查找JVM堆外内存泄漏发生的位置

如何解决为什么以及如何查找JVM堆外内存泄漏发生的位置

我有一个Java项目,该项目显示了产品环境中的内存泄漏。我们可以看到它的内存使用'top'或'cat / proc / PID / status | grep VmRSS'扩展并越来越大,但是它的JVM堆保持良好状态,这意味着堆内存由'- Xmx”和其他JVM选项。我曾经使用jmap/dump/jstack和我知道的任何其他命令来分析出了什么问题,但是徒劳。

最后,我们通过逐行测试发现了问题。这是JVM JavaScript引擎中的问题。我在这里提取了可以重现该问题的代码

package com.unionpay.cqp.arch.js;


import javax.script.*;


import static java.lang.Thread.sleep;


public class JsEngineMain {
    private static final ScriptEngine SCRIPT_ENGINE = new ScriptEngineManager().getEngineByName("JavaScript");
    private static final String SCRIPT_FUNC_1 = "function max_num(a,b){return (a>b)?a:b;} ";


    public static void main(String[] args) {
        if (args == null || args.length < 1) {
            System.out.println("wrong args,use like:");
            System.out.println("java -jar xxx.jar SLEEP_TIME_MILLIES");
            System.out.println("java -cp xxx.jar com.unionpay.cqp.arch.js.JsEngineMainBak SLEEP_TIME_MILLIES");
            return;
        }
        long sleepTime = Long.parseLong(args[0]);
        try {
            while (true) {
                sleep(sleepTime);
                testLoopFuncString();
            }
        } catch (Exception e) {
            e.printstacktrace();
        }
    }


    private static void testLoopFuncString() {
        try {
            Compilable compilable = (Compilable) SCRIPT_ENGINE;
            CompiledScript compiledScript = compilable.compile(SCRIPT_FUNC_1);
            compiledScript.eval();
            invocable invocable = (invocable) SCRIPT_ENGINE;
            Object res = invocable.invokeFunction("max_num",6,1);
            showRes(res);
        } catch (Exception e) {
            e.printstacktrace();
        }
    }


    private static void showRes(Object res) {
        if (System.currentTimeMillis() % 20000 == 1) {
            System.out.println(res);
        }
    }
}

您可以使用以下命令运行它:

java -Xmx 128M -XX:MaxMetaspaceSize=64M -XX:MaxDirectMemorySize=64M -cp js-engine-test.jar com.unionpay.cqp.arch.js.JsEngineMain 2

并使用以下命令监视内存使用情况:

while true; do cat /proc/PID/status|grep VmRSS;sleep 5;done

然后您将看到内存使用量随时间增长。

好吧,我的问题是,如果我们不知道问题出在哪里,该如何找到问题?以及我们如何通过内存分析或命令工具找到不正确的代码

我使用pmapjcmd来查看内存的占用位置,我可以从jcmd工具获取一些信息,并且我知道这是一个堆外问题。但我无法将其与代码连接,因此找不到代码的哪一行不正确。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。