Skip to content

Commit 7d586f6

Browse files
committed
MemoryHistogramProvider and ThreadInfoProvider refactored to remove duplicate code
1 parent 1ccd60f commit 7d586f6

File tree

4 files changed

+240
-240
lines changed

4 files changed

+240
-240
lines changed
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*
2+
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package org.graalvm.visualvm.sampler.truffle;
26+
27+
import java.io.IOException;
28+
import java.util.Map;
29+
import javax.management.Attribute;
30+
import javax.management.AttributeNotFoundException;
31+
import javax.management.InstanceNotFoundException;
32+
import javax.management.InvalidAttributeValueException;
33+
import javax.management.MBeanException;
34+
import javax.management.MBeanServerConnection;
35+
import javax.management.MalformedObjectNameException;
36+
import javax.management.ObjectName;
37+
import javax.management.ReflectionException;
38+
39+
/**
40+
*
41+
* @author Tomas Hurka
42+
*/
43+
public class ProxyTruffleMBean {
44+
45+
private static final String TRUFFLE_OBJECT_NAME = "com.truffle:type=Threading";
46+
private final ObjectName truffleObjectName;
47+
private final MBeanServerConnection conn;
48+
49+
public ProxyTruffleMBean(MBeanServerConnection c) throws MalformedObjectNameException {
50+
conn = c;
51+
truffleObjectName = new ObjectName(TRUFFLE_OBJECT_NAME);
52+
}
53+
54+
public Map<String, Object>[] dumpAllThreads() throws InstanceNotFoundException, MBeanException, ReflectionException, IOException {
55+
return (Map[]) conn.invoke(truffleObjectName, "dumpAllThreads", null, null);
56+
}
57+
58+
public boolean isStackTracesEnabled() throws InstanceNotFoundException, MBeanException, IOException, ReflectionException, AttributeNotFoundException {
59+
return (boolean) conn.getAttribute(truffleObjectName, "StackTracesEnabled");
60+
}
61+
62+
public Map<String, Object>[] heapHistogram() throws InstanceNotFoundException, MBeanException, ReflectionException, IOException {
63+
return (Map[]) conn.invoke(truffleObjectName, "heapHistogram", null, null);
64+
}
65+
66+
public boolean isHeapHistogramEnabled() throws InstanceNotFoundException, MBeanException, IOException, ReflectionException, AttributeNotFoundException {
67+
return (boolean) conn.getAttribute(truffleObjectName, "HeapHistogramEnabled");
68+
}
69+
70+
public void setTrackFlags(boolean trackFlags) throws InstanceNotFoundException, AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException, IOException {
71+
conn.setAttribute(truffleObjectName, new Attribute("TrackFlags", trackFlags));
72+
}
73+
74+
public void setMode(String mode) throws InstanceNotFoundException, MBeanException, ReflectionException, IOException, AttributeNotFoundException, InvalidAttributeValueException {
75+
conn.setAttribute(truffleObjectName, new Attribute("Mode", mode));
76+
}
77+
78+
public boolean isRegistered() throws IOException {
79+
return conn.isRegistered(truffleObjectName);
80+
}
81+
}
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
/*
2+
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package org.graalvm.visualvm.sampler.truffle;
26+
27+
import com.sun.tools.attach.AgentInitializationException;
28+
import com.sun.tools.attach.AgentLoadException;
29+
import com.sun.tools.attach.AttachNotSupportedException;
30+
import com.sun.tools.attach.VirtualMachine;
31+
import java.io.File;
32+
import java.io.IOException;
33+
import java.util.logging.Level;
34+
import java.util.logging.Logger;
35+
import javax.management.MBeanServerConnection;
36+
import javax.management.MalformedObjectNameException;
37+
import org.graalvm.visualvm.application.Application;
38+
import org.graalvm.visualvm.core.datasupport.Stateful;
39+
import org.graalvm.visualvm.sampler.truffle.memory.MemoryHistogramProvider;
40+
import org.graalvm.visualvm.tools.jmx.JmxModel;
41+
import org.graalvm.visualvm.tools.jmx.JmxModelFactory;
42+
import org.openide.modules.InstalledFileLocator;
43+
import org.openide.modules.ModuleInfo;
44+
import org.openide.modules.Modules;
45+
import org.openide.util.Exceptions;
46+
import org.openide.util.NbBundle;
47+
48+
/**
49+
*
50+
* @author Tomas Hurka
51+
*/
52+
public abstract class TruffleDataProvider {
53+
54+
protected static final Logger LOGGER = Logger.getLogger(TruffleDataProvider.class.getName());
55+
private static String AGENT_PATH = "modules/ext/stagent.jar"; // NOI18N
56+
57+
protected String status;
58+
protected ProxyTruffleMBean tbean;
59+
60+
protected static String initJMXConn(Application application) {
61+
if (application.getState() != Stateful.STATE_AVAILABLE) {
62+
return NbBundle.getMessage(TruffleDataProvider.class, "MSG_unavailable"); // NOI18N
63+
}
64+
JmxModel jmxModel = JmxModelFactory.getJmxModelFor(application);
65+
if (jmxModel == null) {
66+
return NbBundle.getMessage(TruffleDataProvider.class, "MSG_unavailable_init_jmx"); // NOI18N
67+
}
68+
if (jmxModel.getConnectionState() != JmxModel.ConnectionState.CONNECTED) {
69+
return NbBundle.getMessage(TruffleDataProvider.class, "MSG_unavailable_create_jmx"); // NOI18N
70+
}
71+
return null;
72+
}
73+
74+
public String getStatus() {
75+
return status;
76+
}
77+
78+
protected boolean checkAndLoadJMX(Application app) throws MalformedObjectNameException, IOException, InterruptedException {
79+
synchronized (app) {
80+
JmxModel jmxModel = JmxModelFactory.getJmxModelFor(app);
81+
tbean = new ProxyTruffleMBean(jmxModel.getMBeanServerConnection());
82+
if (tbean.isRegistered()) {
83+
return true;
84+
}
85+
if (loadAgent(app)) {
86+
for (int i = 0; i < 10; i++) {
87+
if (tbean.isRegistered()) {
88+
return true;
89+
}
90+
Thread.sleep(300);
91+
}
92+
}
93+
return tbean.isRegistered();
94+
}
95+
}
96+
97+
private boolean loadAgent(Application app) {
98+
String pid = String.valueOf(app.getPid());
99+
String agentPath = getAgentPath();
100+
101+
LOGGER.warning("Agent " + agentPath); // NOI18N
102+
try {
103+
VirtualMachine vm = VirtualMachine.attach(pid);
104+
LOGGER.warning(vm.toString());
105+
loadAgentIntoTargetJVM(vm, agentPath, null);
106+
vm.detach();
107+
LOGGER.warning("Agent loaded"); // NOI18N
108+
return true;
109+
} catch (AttachNotSupportedException ex) {
110+
Exceptions.printStackTrace(ex);
111+
} catch (IOException ex) {
112+
Exceptions.printStackTrace(ex);
113+
} catch (AgentLoadException ex) {
114+
Exceptions.printStackTrace(ex);
115+
} catch (AgentInitializationException ex) {
116+
LOGGER.log(Level.INFO, "loadAgent()", ex);
117+
}
118+
return false;
119+
}
120+
121+
private static void loadAgentIntoTargetJVM(final VirtualMachine virtualMachine, final String jar, final String options)
122+
throws IOException, AgentLoadException, AgentInitializationException {
123+
try {
124+
virtualMachine.loadAgent(jar, options);
125+
} catch (AgentLoadException ex) {
126+
if ("0".equals(ex.getMessage())) {
127+
// JDK 10 -> JDK 9 mismatch
128+
return;
129+
}
130+
throw ex;
131+
} catch (IOException ex) {
132+
if ("readInt".equals(ex.getStackTrace()[0].getMethodName())) {
133+
// JDK 9 -> JDK 10 mismatch
134+
return;
135+
}
136+
throw ex;
137+
}
138+
}
139+
140+
private String getAgentPath() {
141+
InstalledFileLocator loc = InstalledFileLocator.getDefault();
142+
ModuleInfo info = Modules.getDefault().ownerOf(getClass());
143+
File jar = loc.locate(AGENT_PATH, info.getCodeNameBase(), false);
144+
145+
return jar.getAbsolutePath();
146+
}
147+
}

0 commit comments

Comments
 (0)