$ ps -aux|grep java
2. 然后以某种方式从ID中获取已加载的类。
我不知道是否可能。请有心人指导我正确的方向吗? P.S.:我正在使用Java通过Process类运行上述命令,类似于以下内容:
Process process = Runtime.getRuntime().exec("ps -ef");
所以我想从一个Java项目中实现它。
$ ps -aux|grep java
2. 然后以某种方式从ID中获取已加载的类。
我不知道是否可能。请有心人指导我正确的方向吗? P.S.:我正在使用Java通过Process类运行上述命令,类似于以下内容:
Process process = Runtime.getRuntime().exec("ps -ef");
我来到这个页面是为了寻找一个食谱“如何查找一个罐子是否已经被装载”(这与原问题有点不同)。但也许对某些人会有用:
我发现jcmd
是获取此信息的最佳方法,例如:
$ jps
1 MyAppLauncher
529 Jps
jcmd
在该JVM中提供了哪些选项:[eceuser@ecs1-0 temp]$ jcmd 1 help
1:
The following commands are available:
JFR.stop
JFR.start
JFR.dump
JFR.check
VM.native_memory
VM.check_commercial_features
VM.unlock_commercial_features
ManagementAgent.stop
ManagementAgent.start_local
ManagementAgent.start
VM.classloader_stats
GC.rotate_log
Thread.print
GC.class_stats
GC.class_histogram
GC.heap_dump
GC.finalizer_info
GC.heap_info
GC.run_finalization
GC.run
VM.uptime
VM.dynlibs
VM.flags
VM.system_properties
VM.command_line
VM.version
help
VM.dynlibs
可以满足我的需求:$ jcmd 1 VM.dynlibs | grep custom
7f59a4b3b000-7f59a4b3d000 r--s 00000000 fd:00 1116085962 /home/app/lib/custom-fi-extensions-0.0.1-SNAPSHOT.jar
你需要在你的应用程序启动命令行中放入某种标识符。例如:
String id = "com.app.demo";
当你运行你的应用程序时,确保包含这个字符串。假设你是从Java中启动它,请执行以下操作:
Runtime.getRuntime().exec("C:\...\javaw.exe -cp ... -Dwhatever=" + id + " com.app.app.demo.Main");
通过id
获取应用程序,类似于$ps aux | grep -i com.app.app.demo
。在Java中调用Runtime.getRuntime().exec("ps aux | grep -i com.app.app.demo");
我更喜欢使用ProcessBuilder(从Java 8开始),并通过bash运行您的命令:
Process process = new ProcessBuilder().command("bash", "ps aux | grep com.app.app.demo").start()
ps aux | grep [j]ava | awk '{print $2}' | xargs -I{} jcmd {} VM.class_hierarchy | grep "org.springframework.boot.logging.LoggingInitializationContext"
它查找包含java
的进程,仅获取PID,并将其传递给jcmd,在其中使用grep搜索特定的类。输出似乎是正确的,唯一的问题是在这个长管道中我丢失了PID,并且不确定如何打印它。
但如果你的问题是“有多少个springboot应用程序”,那么这可能不是一个问题。我也不确定在使用jcmd VM.class_hierarchy
时类是否会出现两次,但看起来并不像是这样。
注意:此方法适用于JDK 11。我先尝试了jmap,但由于某些原因在JDK 11上对我不起作用。
快速而简单的方法:在你的类中添加一些静态块,并在其中打印一些内容到日志(或者系统输出)。静态块在类被类加载器加载时执行,而不是在第一个实例化时执行(这是在第一次调用构造函数时执行)。然后,如果你的打印输出在日志中,那么该类已经被加载。示例:
public class Sample {
private static final Logger logger = ...
static {
logger.info("class Sample is loaded");
}
...
}
ps ... | grep ....
命令。在Linux中,您可以至少使用ps -fC java
列出所有执行java
的进程。更好的方法是使用Oracle JDK自带的工具来列出系统上的Java进程:jps
。然而,这个命令只会列出同一用户的进程。 - undefined