Skip to content

Commit 9bd3a30

Browse files
committed
Command line options --start-cpu-sampler <pid>[@settings] and --start-memory-sampler <pid>[@settings] and --snapshot-sampler <pid> and --stop-sampler <pid>
1 parent bcd4e95 commit 9bd3a30

15 files changed

+643
-8
lines changed

visualvm/sampler/manifest.mf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@ Manifest-Version: 1.0
22
AutoUpdate-Show-In-Client: false
33
OpenIDE-Module: org.graalvm.visualvm.sampler/2
44
OpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/sampler/Bundle.properties
5-
OpenIDE-Module-Specification-Version: 2.0
5+
OpenIDE-Module-Specification-Version: 2.1
66
OpenIDE-Module-Layer: org/graalvm/visualvm/sampler/resources/layer.xml
77
OpenIDE-Module-Install: org/graalvm/visualvm/sampler/Installer.class

visualvm/sampler/nbproject/project.xml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
<compile-dependency/>
1313
<run-dependency>
1414
<release-version>2</release-version>
15-
<specification-version>2.0</specification-version>
15+
<specification-version>2.1</specification-version>
1616
</run-dependency>
1717
</dependency>
1818
<dependency>
@@ -140,6 +140,15 @@
140140
<specification-version>1.48</specification-version>
141141
</run-dependency>
142142
</dependency>
143+
<dependency>
144+
<code-name-base>org.netbeans.modules.sendopts</code-name-base>
145+
<build-prerequisite/>
146+
<compile-dependency/>
147+
<run-dependency>
148+
<release-version>2</release-version>
149+
<specification-version>2.43</specification-version>
150+
</run-dependency>
151+
</dependency>
143152
<dependency>
144153
<code-name-base>org.openide.dialogs</code-name-base>
145154
<build-prerequisite/>

visualvm/sampler/src/org/graalvm/visualvm/sampler/AbstractSamplerSupport.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ public abstract class AbstractSamplerSupport {
4040
public abstract DataViewComponent.DetailsView[] getDetailsView();
4141

4242
public abstract boolean startSampling(ProfilingSettings settings, int samplingRate, int refreshRate);
43+
44+
public abstract void takeSnapshot(boolean openView);
4345

4446
public abstract void stopSampling();
4547

visualvm/sampler/src/org/graalvm/visualvm/sampler/ApplicationSamplerView.java

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ final class ApplicationSamplerView extends DataSourceView {
4545
private static final String IMAGE_PATH = "org/graalvm/visualvm/sampler/resources/sampler.png"; // NOI18N
4646

4747
private SamplerImpl sampler;
48+
private SamplerArguments.Request startRequest = SamplerArguments.Request.NONE;
49+
private SamplerParameters settingsRequest;
4850

4951
private ApplicationListener applicationListener;
5052

@@ -54,12 +56,39 @@ final class ApplicationSamplerView extends DataSourceView {
5456
new ImageIcon(ImageUtilities.loadImage(IMAGE_PATH, true)).getImage(), 35, false);
5557

5658
}
59+
60+
61+
void startCPU(SamplerParameters settings) {
62+
if (sampler != null) {
63+
sampler.startCPU(settings);
64+
} else {
65+
startRequest = SamplerArguments.Request.CPU;
66+
settingsRequest = settings;
67+
}
68+
}
69+
70+
void startMemory(SamplerParameters settings) {
71+
if (sampler != null) {
72+
sampler.startMemory(settings);
73+
} else {
74+
startRequest = SamplerArguments.Request.MEMORY;
75+
settingsRequest = settings;
76+
}
77+
}
78+
79+
void takeSnapshot(boolean openView) {
80+
if (sampler != null) sampler.takeSnapshot(openView);
81+
}
82+
83+
void stop() {
84+
if (sampler != null) sampler.stop();
85+
}
5786

5887

5988
protected void willBeAdded() {
6089
Application application = (Application)getDataSource();
6190

62-
sampler = new SamplerImpl(application);
91+
sampler = new SamplerImpl(application, startRequest, settingsRequest);
6392

6493
applicationListener = new ApplicationListener() {
6594
public void dataRemoved(Application application) { applicationFinished(); }

visualvm/sampler/src/org/graalvm/visualvm/sampler/Bundle.properties

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,3 +122,13 @@ MSG_Incorrect_Memory_settings=Provided Memory settings are invalid.
122122
MSG_High_Sampling_Frequency=<html><br><b>Configured sampling frequency is high.</b><br><br>This may affect performance of the target application<br>and bias the collected results.<br><br></html>
123123

124124
CAP_High_Sampling_Frequency=High Sampling Frequency
125+
126+
Argument_StartCpu_ShortDescr=start CPU sampler for the provided process
127+
128+
Argument_StartMemory_ShortDescr=start Memory sampler for the provided process
129+
130+
Argument_Snapshot_ShortDescr=take sampler snapshot for the provided process
131+
132+
Argument_Stop_ShortDescr=stop sampling the provided process
133+
134+
MSG_NO_APP_PID = Cannot find application with pid {0}.
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
/*
2+
* Copyright (c) 2021, 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;
26+
27+
import java.util.HashSet;
28+
import java.util.Map;
29+
import java.util.Set;
30+
import org.graalvm.visualvm.application.Application;
31+
import org.graalvm.visualvm.application.ApplicationFinder;
32+
import org.netbeans.api.sendopts.CommandException;
33+
import org.netbeans.spi.sendopts.Env;
34+
import org.netbeans.spi.sendopts.Option;
35+
import org.netbeans.spi.sendopts.OptionProcessor;
36+
import org.openide.DialogDisplayer;
37+
import org.openide.NotifyDescriptor;
38+
import org.openide.util.NbBundle;
39+
import org.openide.util.lookup.ServiceProvider;
40+
41+
/**
42+
*
43+
* @author Jiri Sedlacek
44+
*/
45+
@ServiceProvider(service=OptionProcessor.class)
46+
public final class SamplerArguments extends OptionProcessor {
47+
48+
private static final String START_CPU_LONG_NAME = "start-cpu-sampler"; // NOI18N
49+
private static final Option START_CPU_ARGUMENT = Option.shortDescription(Option.requiredArgument(Option.NO_SHORT_NAME, START_CPU_LONG_NAME), "org.graalvm.visualvm.sampler", "Argument_StartCpu_ShortDescr"); // NOI18N
50+
private static final String START_MEMORY_LONG_NAME = "start-memory-sampler";// NOI18N
51+
private static final Option START_MEMORY_ARGUMENT = Option.shortDescription(Option.requiredArgument(Option.NO_SHORT_NAME, START_MEMORY_LONG_NAME), "org.graalvm.visualvm.sampler", "Argument_StartMemory_ShortDescr"); // NOI18N
52+
private static final String SNAPSHOT_LONG_NAME = "snapshot-sampler"; // NOI18N
53+
private static final Option SNAPSHOT_ARGUMENT = Option.shortDescription(Option.requiredArgument(Option.NO_SHORT_NAME, SNAPSHOT_LONG_NAME), "org.graalvm.visualvm.sampler", "Argument_Snapshot_ShortDescr"); // NOI18N
54+
private static final String STOP_LONG_NAME = "stop-sampler"; // NOI18N
55+
private static final Option STOP_ARGUMENT = Option.shortDescription(Option.requiredArgument(Option.NO_SHORT_NAME, STOP_LONG_NAME), "org.graalvm.visualvm.sampler", "Argument_Stop_ShortDescr"); // NOI18N
56+
57+
static enum Request { NONE, CPU, MEMORY };
58+
59+
60+
@Override
61+
protected Set<Option> getOptions() {
62+
Set<Option> options = new HashSet();
63+
options.add(START_CPU_ARGUMENT);
64+
options.add(START_MEMORY_ARGUMENT);
65+
options.add(SNAPSHOT_ARGUMENT);
66+
options.add(STOP_ARGUMENT);
67+
return options;
68+
}
69+
70+
@Override
71+
protected void process(Env env, Map<Option, String[]> maps) throws CommandException {
72+
String[] startCPU = maps.get(START_CPU_ARGUMENT);
73+
if (startCPU != null) {
74+
final String[] _startCPU = startCPU.length == 1 ? startCPU[0].split("@") : null; // NOI18N
75+
if (_startCPU != null && _startCPU.length == 2) startCPU[0] = _startCPU[0];
76+
new Finder(startCPU, START_CPU_LONG_NAME) {
77+
@Override
78+
public void found(Application application) {
79+
String settings = _startCPU != null && _startCPU.length == 2 ? _startCPU[1] : null;
80+
SamplerSupport.getInstance().startCPU(application, settings);
81+
}
82+
}.find();
83+
return;
84+
}
85+
86+
String[] startMemory = maps.get(START_MEMORY_ARGUMENT);
87+
if (startMemory != null) {
88+
final String[] _startMemory = startMemory.length == 1 ? startMemory[0].split("@") : null; // NOI18N
89+
if (_startMemory != null && _startMemory.length == 2) startMemory[0] = _startMemory[0];
90+
new Finder(startMemory, START_MEMORY_LONG_NAME) {
91+
@Override
92+
public void found(Application application) {
93+
String settings = _startMemory != null && _startMemory.length == 2 ? _startMemory[1] : null;
94+
SamplerSupport.getInstance().startMemory(application, settings);
95+
}
96+
}.find();
97+
return;
98+
}
99+
100+
final String[] snapshot = maps.get(SNAPSHOT_ARGUMENT);
101+
final String[] stop = maps.get(STOP_ARGUMENT);
102+
if (snapshot != null) {
103+
new Finder(snapshot, SNAPSHOT_LONG_NAME) {
104+
@Override
105+
public void found(Application application) {
106+
SamplerSupport.getInstance().takeSnapshot(application, true);
107+
if (stop != null && stop.length == 1 && stop[0].equals(snapshot[0]))
108+
SamplerSupport.getInstance().stop(application);
109+
}
110+
}.find();
111+
return;
112+
}
113+
114+
if (stop != null) {
115+
new Finder(stop, STOP_LONG_NAME) {
116+
@Override
117+
public void found(Application application) {
118+
SamplerSupport.getInstance().stop(application);
119+
}
120+
}.find();
121+
}
122+
}
123+
124+
125+
private static abstract class Finder extends ApplicationFinder {
126+
127+
Finder(String[] pids, String longName) throws CommandException {
128+
super(resolvePid(pids, longName));
129+
}
130+
131+
132+
public final void notFound(int pid, String id) {
133+
NotifyDescriptor desc = new NotifyDescriptor.Message(NbBundle.getMessage(SamplerArguments.class, "MSG_NO_APP_PID", new Object[] { Integer.toString(pid) }), NotifyDescriptor.WARNING_MESSAGE);
134+
DialogDisplayer.getDefault().notifyLater(desc);
135+
}
136+
137+
138+
private static int resolvePid(String[] pids, String longName) throws CommandException {
139+
if (pids.length == 1) {
140+
try {
141+
return Integer.valueOf(pids[0]);
142+
} catch (NumberFormatException e) {
143+
throw new CommandException(0, "Incorrect pid format for --" + longName + ": " + e.getMessage()); // NOI18N
144+
}
145+
} else {
146+
throw new CommandException(0, "--" + longName + " requires exactly one value"); // NOI18N
147+
}
148+
}
149+
150+
}
151+
152+
}

visualvm/sampler/src/org/graalvm/visualvm/sampler/SamplerImpl.java

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,10 +133,14 @@ private static enum State { TERMINATED, INACTIVE, CPU, MEMORY, TRANSITION };
133133
private DataViewComponent.DetailsView[] currentViews;
134134

135135
private State state = State.TRANSITION;
136+
private SamplerArguments.Request startRequest;
137+
private SamplerParameters settingsRequest;
136138

137139

138-
SamplerImpl(Application application) {
140+
SamplerImpl(Application application, SamplerArguments.Request startRequest, SamplerParameters settingsRequest) {
139141
this.application = application;
142+
this.startRequest = startRequest;
143+
this.settingsRequest = settingsRequest;
140144

141145
cpuSettings = new CPUSettingsSupport() {
142146
public boolean presetValid() {
@@ -158,6 +162,32 @@ public PresetSelector createSelector(Runnable presetSynchronizer) {
158162
};
159163
}
160164

165+
166+
void startCPU(SamplerParameters parameters) {
167+
if (parameters != null && !parameters.isEmpty()) cpuSettings.setSettings(parameters);
168+
if (!cpuProfilingSupported) startRequest = SamplerArguments.Request.CPU; // likely not initialized yet, perform lazily
169+
else if (cpuButton != null && cpuButton.isEnabled() && !cpuButton.isSelected()) cpuButton.doClick();
170+
}
171+
172+
void startMemory(SamplerParameters parameters) {
173+
if (parameters != null && !parameters.isEmpty()) memorySettings.setSettings(parameters);
174+
if (!memoryProfilingSupported) startRequest = SamplerArguments.Request.MEMORY; // likely not initialized yet, perform lazily
175+
else if (memoryButton != null && memoryButton.isEnabled() && !memoryButton.isSelected()) memoryButton.doClick();
176+
}
177+
178+
void takeSnapshot(boolean openView) {
179+
if (cpuSampler != null && State.CPU.equals(getState())) {
180+
cpuSampler.takeSnapshot(openView);
181+
} else if (memorySampler != null && State.MEMORY.equals(getState())) {
182+
memorySampler.takeSnapshot(openView);
183+
}
184+
}
185+
186+
void stop() {
187+
if (stopButton != null && stopButton.isEnabled()) stopButton.doClick();
188+
}
189+
190+
161191
private PresetSelector createSelector(Runnable presetSynchronizer) {
162192
if (selectorModel == null) selectorModel = new DefaultComboBoxModel();
163193
if (allSelectors == null) allSelectors = new ArrayList();
@@ -592,6 +622,7 @@ public void run() {
592622
refreshSummary();
593623
updateButtons();
594624
updateSettings();
625+
if (SamplerArguments.Request.CPU.equals(startRequest)) startCPU(settingsRequest);
595626
}
596627
});
597628
}
@@ -787,6 +818,7 @@ public void run() {
787818
refreshSummary();
788819
updateButtons();
789820
updateSettings();
821+
if (SamplerArguments.Request.MEMORY.equals(startRequest)) startMemory(settingsRequest);
790822
}
791823
});
792824
}

0 commit comments

Comments
 (0)