在离线模式下将 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>
为前缀的消息。本机 stderr 日志还将包含有关已保存快照的消息。或者,调用控制器的代码可能根本不被调用。
【参考方案1】:
控制器类仅在加载分析代理的 JVM 中起作用,通常通过使用 -agentpath:
VM 参数启动 JVM。
在您的情况下,您在未加载分析代理的进程中调用控制器类,因此调用无效。此外,这些调用对子进程没有任何影响。
您必须将对控制器类的调用移动到子进程中才能使其工作。
【讨论】:
啊,太有趣了,我试图解决一些实际上是“按设计”的行为......如何自动分析另一个进程?我需要能够执行一些操作,开始分析,执行一些其他操作,然后停止分析并创建快照,并从正在分析的不同进程中执行此操作。谢谢! 您可以使用 JProfiler MBean 做到这一点。请参阅api/samples/mbean
中的示例。从 JProfiler 11 开始,jpcontroller
将采用非交互模式,无需使用任何代码即可实现。以上是关于在离线模式下将 Jprofiler Controller 与 weblogic 进程一起使用的主要内容,如果未能解决你的问题,请参考以下文章
如何在离线模式下从 Apple Watch 导入使用 HealthKit 的步骤?