diff --git a/com.osgifx.console.agent.api/src/main/java/com/osgifx/console/agent/Agent.java b/com.osgifx.console.agent.api/src/main/java/com/osgifx/console/agent/Agent.java index 0d889547..adf13ab0 100644 --- a/com.osgifx.console.agent.api/src/main/java/com/osgifx/console/agent/Agent.java +++ b/com.osgifx.console.agent.api/src/main/java/com/osgifx/console/agent/Agent.java @@ -622,5 +622,5 @@ public interface Agent { /** * Performs a garbage collection */ - void gc(); + void gc() throws Exception; } diff --git a/com.osgifx.console.agent/src/main/java/com/osgifx/console/agent/admin/XHeapAdmin.java b/com.osgifx.console.agent/src/main/java/com/osgifx/console/agent/admin/XJmxAdmin.java similarity index 86% rename from com.osgifx.console.agent/src/main/java/com/osgifx/console/agent/admin/XHeapAdmin.java rename to com.osgifx.console.agent/src/main/java/com/osgifx/console/agent/admin/XJmxAdmin.java index 4187dfb4..efb9c0d6 100644 --- a/com.osgifx.console.agent/src/main/java/com/osgifx/console/agent/admin/XHeapAdmin.java +++ b/com.osgifx.console.agent/src/main/java/com/osgifx/console/agent/admin/XJmxAdmin.java @@ -37,7 +37,7 @@ import com.osgifx.console.agent.dto.XHeapUsageDTO.XMemoryPoolMXBean; import com.osgifx.console.agent.dto.XHeapUsageDTO.XMemoryUsage; -public final class XHeapAdmin { +public final class XJmxAdmin { private static final String HOTSPOT_BEAN_NAME = "com.sun.management:type=HotSpotDiagnostic"; private static volatile Object hotspotMBean; @@ -110,9 +110,25 @@ public byte[] heapdump() throws Exception { } } + public void gc() throws Exception { + initHotspotMBean(); + final Class clazzBean = Class.forName("com.sun.management.HotSpotDiagnosticMXBean"); + final Class clazzVMOption = Class.forName("com.sun.management.VMOption"); + final Method method1 = clazzBean.getMethod("getVMOption", String.class); + final Method method2 = clazzVMOption.getMethod("getValue"); + final Object vmOption = method1.invoke(hotspotMBean, "DisableExplicitGC"); + final Object vmOptionValue = method2.invoke(vmOption); + + if (vmOptionValue != null && "true".equalsIgnoreCase(vmOptionValue.toString())) { + logger.atInfo().msg("Explicit GC invocation is disabled").log(); + return; + } + System.gc(); + } + private static void initHotspotMBean() throws Exception { if (hotspotMBean == null) { - synchronized (XHeapAdmin.class) { + synchronized (XJmxAdmin.class) { if (hotspotMBean == null) { hotspotMBean = getHotspotMBean(); } diff --git a/com.osgifx.console.agent/src/main/java/com/osgifx/console/agent/provider/AgentServer.java b/com.osgifx.console.agent/src/main/java/com/osgifx/console/agent/provider/AgentServer.java index d3c43b28..3e4a1f48 100644 --- a/com.osgifx.console.agent/src/main/java/com/osgifx/console/agent/provider/AgentServer.java +++ b/com.osgifx.console.agent/src/main/java/com/osgifx/console/agent/provider/AgentServer.java @@ -101,8 +101,8 @@ import com.osgifx.console.agent.admin.XDtoAdmin; import com.osgifx.console.agent.admin.XEventAdmin; import com.osgifx.console.agent.admin.XHcAdmin; -import com.osgifx.console.agent.admin.XHeapAdmin; import com.osgifx.console.agent.admin.XHttpAdmin; +import com.osgifx.console.agent.admin.XJmxAdmin; import com.osgifx.console.agent.admin.XLogReaderAdmin; import com.osgifx.console.agent.admin.XLoggerAdmin; import com.osgifx.console.agent.admin.XMetaTypeAdmin; @@ -992,7 +992,7 @@ public List getHttpComponents() { public XHeapUsageDTO getHeapUsage() { final boolean isJMXWired = di.getInstance(PackageWirings.class).isJmxWired(); if (isJMXWired) { - return di.getInstance(XHeapAdmin.class).init(); + return di.getInstance(XJmxAdmin.class).init(); } logger.atWarn().msg(packageNotWired(JMX)).log(); return null; @@ -1004,15 +1004,21 @@ public RuntimeDTO getRuntimeDTO() { } @Override - public void gc() { + public void gc() throws Exception { + final boolean isJMXWired = di.getInstance(PackageWirings.class).isJmxWired(); + if (isJMXWired) { + di.getInstance(XJmxAdmin.class).gc(); + return; + } System.gc(); + logger.atWarn().msg(packageNotWired(JMX)).log(); } @Override public byte[] heapdump() throws Exception { final boolean isJMXWired = di.getInstance(PackageWirings.class).isJmxWired(); if (isJMXWired) { - return di.getInstance(XHeapAdmin.class).heapdump(); + return di.getInstance(XJmxAdmin.class).heapdump(); } logger.atWarn().msg(packageNotWired(JMX)).log(); return null; diff --git a/com.osgifx.console.ui.heap/src/main/java/com/osgifx/console/ui/heap/HeapMonitorPane.java b/com.osgifx.console.ui.heap/src/main/java/com/osgifx/console/ui/heap/HeapMonitorPane.java index 323003ef..2981baf5 100644 --- a/com.osgifx.console.ui.heap/src/main/java/com/osgifx/console/ui/heap/HeapMonitorPane.java +++ b/com.osgifx.console.ui.heap/src/main/java/com/osgifx/console/ui/heap/HeapMonitorPane.java @@ -300,7 +300,25 @@ private void performGC() { if (agent == null) { return; } - executor.runAsync(agent::gc); + final Task gcTask = new Task<>() { + + @Override + protected Void call() throws Exception { + try { + updateMessage("Performing GC"); + agent.gc(); + return null; + } catch (final Exception e) { + logger.atError().withException(e).log("Cannot perform GC"); + threadSync.asyncExec(() -> { + progressDialog.close(); + FxDialog.showExceptionDialog(e, getClass().getClassLoader()); + }); + throw e; + } + } + }; + executor.runAsync(gcTask); } private void heapDump() {