是否可以在命令行中使用JMX在Linux(CentOS)上运行的进程上获取服务器堆转储?
无法打开VisualVM, 无法安装jmap
答案 0 :(得分:1)
可以使用这个简单的代码完成:
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:app="http://schemas.android.com/tools"
android:id="@+id/card_view"
android:layout_height="80dp"
android:layout_width="match_parent"
android:layout_marginBottom="16dp"
app:cardCornerRadius="16dp"
app:cardElevation="16dp"
card_view:cardCornerRadius="16dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
app:cardPreventCornerOverlap="false"
app:cardUseCompatPadding="true"
card_view:cardBackgroundColor="@android:color/black"
android:divider="#B49238"
>
<ImageView
android:layout_width="40dp"
android:layout_height="40dp"
android:src="@drawable/cancel"
android:layout_marginLeft="1200dp"
android:layout_marginTop="18dp"
android:id="@+id/imageView19" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_toStartOf="@+id/imageView16">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Large Text"
android:id="@+id/textView"
android:textSize="30dp"
android:singleLine="true"
android:focusable="false"
android:focusableInTouchMode="false"
android:layout_marginStart="100dp"
android:layout_marginTop="18dip"
android:textColor="@color/tabsScrollColor"
android:layout_alignParentTop="true"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text=""
android:id="@+id/textView11" />
</LinearLayout>
<ImageView
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_marginEnd="10dp"
android:id="@+id/button"
android:src="@drawable/musicalbum"
android:padding="5dp"
android:focusable="false"
android:layout_marginStart="10dp"
android:layout_marginTop="7dip"
android:layout_alignParentRight="true"
/>
从命令行调用它:
@SuppressWarnings("restriction")
public class CreateHeapDump
{
public static void main(String[] args) throws Exception
{
String host = args[0];
String port = args[1];
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + host + ":" + port + "/jmxrmi");
JMXConnector jmxc = JMXConnectorFactory.connect(url, null);
MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();
ObjectName mbeanName = new ObjectName("com.sun.management:type=HotSpotDiagnostic");
HotSpotDiagnosticMXBean bean = JMX.newMBeanProxy(mbsc, mbeanName, HotSpotDiagnosticMXBean.class, true);
String fileName = "heap_dump_" + new SimpleDateFormat("dd.MM.yyyy HH.mm").format(new Date()) + ".hprof";
boolean onlyLiveObjects = true;
bean.dumpHeap(fileName, onlyLiveObjects);
}
}
答案 1 :(得分:0)
这不会很漂亮,但它确实有效。话虽如此,您可能要考虑在Groovy或Jython中编写脚本,甚至是JavaScript .... 我在jmxlocal添加了一个quickie加载项,这是一个为本地JVM实现标准JMX远程处理的项目。它现在支持针对连接的MBeanServer的一个命令的命令行调用,并且必须在Java代码中指定该命令。
克隆回购并使用 mvn clean install 进行构建。 将jar( jmxlocal-1.0-SNAPSHOT.jar )复制到目标服务器。 使用目标java进程的PID执行dump JMX命令,如下所示:
java -jar target/jmxlocal-1.0-SNAPSHOT.jar -j service:jmx:attach:///<PID> -c "conn.invoke(on(\"com.sun.management:type=HotSpotDiagnostic\"), \"dumpHeap\", new Object[]{\"/tmp/heap.dump\", true}, new String[]{String.class.getName(), boolean.class.getName()})"
输出
Command Executed. Result [null]
你应该在 /tmp/heap.dump 找到转储文件。
如果需要,您可以使用 -u [用户名] 和 -p [密码] 参数提供凭据。