在离线模式下将 Jprofiler Controller 与 weblogic 进程一起使用

Posted

技术标签:

【中文标题】在离线模式下将 Jprofiler Controller 与 weblogic 进程一起使用【英文标题】:Using Jprofiler Controller with weblogic process in offline mode 【发布时间】:2018-12-11 16:04:09 【问题描述】:

我正在尝试基于 demos\api\samples\offline\ 示例使用 Controller Java API 以离线模式分析在 Weblogic 上运行的应用程序。

我的问题是没有创建 .jps 文件,尽管 Controller.saveSnapshot() 退出时没有错误。

    我创建了一个会话配置,当我在 GUI 中附加到进程时它运行良好。

    我将 config.xml 文件从 home 复制到工作目录。

    我在server start 中为我的服务更新了 JVM 参数,其中包含以下行:

    -agentpath:/home/alex/jprofiler10/bin/linux-x64/libjprofilerti.so=offline,id=116,config=/workdir/config_bak.xml

    我创建了一个 Java 程序,它启动 CPU 分析然后结束 CPU 分析并尝试保存分析结果。

    Controller.startCPURecording(true); performProfiledTask(); Controller.stopCPURecording();

    字符串 fName = "test.jps"; System.out.println("保存快照:"+fName); Controller.saveSnapshot(new File(fName)); System.out.println("保存的快照:"+fName);

程序执行没有错误,但没有创建快照文件。

我尝试使用 sudo 权限运行它,结果相同。


编辑:

也许我不明白,但在我看来,如果控制器仅在与分析代码相同的进程中运行,则 JProfiler 离线工作。

当它在不同的\子进程中运行时,文件不会被创建。

例如,我希望创建文件的以下代码没有这样做。

分析过程:

import java.io.File;
import java.io.IOException;

import com.jprofiler.api.controller.Controller;

//turn on profiling and run a child process with offline profiling enabled in agentpath
public class PerfDemo 

    public static void main(String[] args) throws IOException 

        System.out.println("Started profiling");

        // On startup, JProfiler does not record any data. The various recording subsystems have to be
        // switched on programatically.
        Controller.startCPURecording(true);

        try 
            exec(CpuIntensiveProcess.class);

         catch (Exception ex) 
            ex.printStackTrace();
            System.out.println("Exception: "+ex.getStackTrace());
        

        // You can switch off recording at any point. Recording can be switched on again.
        Controller.stopCPURecording();
        saveSnapshot("snapshot.jps");              
    

    private static void saveSnapshot(String fileName)
        System.out.println("saving snapshot: "+fileName);
        Controller.saveSnapshot(new File(fileName));        
    

    //execute a new process with offline profiling enabled in agentpath
    public static int exec(Class klass) throws IOException, InterruptedException

            String javaHome = System.getProperty("java.home");
            String javaBin = javaHome +
            File.separator + "bin" +
            File.separator + "java";
            String classpath = System.getProperty("java.class.path");
            String className = klass.getName();

            ProcessBuilder builder = new ProcessBuilder(
            javaBin, "-cp", classpath, "-agentpath:\"c:\\\\Progra~1\\\\jprofiler10\\\\bin\\\\windows-x64\\\\jprofilerti.dll\"=offline,id=110,config=config.xml", className );

            System.out.println("starting process");
            Process process = builder.inheritIO().start();
            process.waitFor();

            System.out.println("process finished");
            return process.exitValue(); 
    

剖析流程:

import static java.lang.Math.*;

import java.io.IOException;

public class CpuIntensiveProcess 

    public static void main(String[] args) throws IOException 
        for (int i=0;i<50000000;i++) 
            double d = tan(atan(tan(atan(tan(atan(tan(atan(tan(atan(123456789.123456789))))))))));
            double h =d+1;
                
       

运行时批处理:

@echo off

SET CLASSPATH=.;jprofiler-controller-10.1.4.jar;agent.jar;
"c:\Program Files\Java\jdk-10.0.1\bin\javac.exe" -cp %CLASSPATH% *.java
java -cp %CLASSPATH% PerfDemo

REM If I run in this configuration, the profiling is of the PerfDemo process and not of the CpuIntensiveProcess process
REM SET AGENTPATH=-agentpath:"c:\\Progra~1\\jprofiler10\\bin\\windows-x64\\jprofilerti.dll"=offline,id=110,config=config.xml
REM java -cp %CLASSPATH%  %AGENTPATH% PerfDemo

set "CURR_DIR=%cd%"
pushd "c:\Program Files\jprofiler10\bin"
jpexport %CURR_DIR%/snapshot.jps -outputdir=%CURR_DIR% HotSpots out.csv
popd

type out.csv

当我运行批处理时,没有创建 .jps 文件。

当我使用 agentpath 运行 PerfDemo 进程时,会创建 jps 文件,但分析属于同一进程,而不是其他进程。

输出:

C:\dev\docs\bak\sample_other_process_profiling>profile.bat
Started profiling
Starting child process...
JProfiler> Protocol version 59
JProfiler> Java 9+ detected.
JProfiler> JVMTI version 1.1 detected.
JProfiler> Offline profiling mode.
JProfiler> 64-bit library
JProfiler> Using config file config.xml (id: 110)
JProfiler> Listening on port: 8849.
JProfiler> Enabling native methods instrumentation.
JProfiler> Can retransform classes.
JProfiler> Can retransform any class.
JProfiler> Native library initialized
JProfiler> VM initialized
JProfiler> Retransforming 7 base class files.
JProfiler> Base classes instrumented.
JProfiler> Using instrumentation
JProfiler> Time measurement: elapsed time
JProfiler> CPU profiling enabled
Child process finished
Saving snapshot: snapshot.jps
Controller.saveSnapshot finished, snapshot should exist on the disk: snapshot.jps
The snapshot file C:\dev\docs\bak\sample_other_process_profiling\snapshot.jps does not exist.
The system cannot find the file specified.

【问题讨论】:

尝试将fName = "test.jps"更改为可写目录中的绝对路径。 我试过了,结果一样。 API 示例对您有用吗? 是的,样本工作并创建了快照。当我在 weblogic 进程配置了离线代理时尝试运行该进程时,它不起作用。 -agentpath VM 参数可能被传递到错误的 JVM 或根本不传递。如果通过,您应该会在本机 stderr 日志中看到以 JProfiler&gt; 为前缀的消息。本机 stderr 日志还将包含有关已保存快照的消息。或者,调用控制器的代码可能根本不被调用。 【参考方案1】:

控制器类仅在加载分析代理的 JVM 中起作用,通常通过使用 -agentpath: VM 参数启动 JVM。

在您的情况下,您在未加载分析代理的进程中调用控制器类,因此调用无效。此外,这些调用对子进程没有任何影响。

您必须将对控制器类的调用移动到子进程中才能使其工作。

【讨论】:

啊,太有趣了,我试图解决一些实际上是“按设计”的行为......如何自动分析另一个进程?我需要能够执行一些操作,开始分析,执行一些其他操作,然后停止分析并创建快照,并从正在分析的不同进程中执行此操作。谢谢! 您可以使用 JProfiler MBean 做到这一点。请参阅api/samples/mbean 中的示例。从 JProfiler 11 开始,jpcontroller 将采用非交互模式,无需使用任何代码即可实现。

以上是关于在离线模式下将 Jprofiler Controller 与 weblogic 进程一起使用的主要内容,如果未能解决你的问题,请参考以下文章

如何在离线模式下从 Apple Watch 导入使用 HealthKit 的步骤?

“Cache-Control: only-if-cached”在离线时失败,即使响应被缓存

在离线模式下获得响应

PDF文件阅读问题仅在离线模式下快速

使用 gps 在离线模式下显示当前位置

如何在 JProfiler 离线模式下使用触发器进行分析时自动获取保留的内存