History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/jvmstat/perfdata/monitor/protocol/rmi/RemoteMonitoredVm.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/jvmstat/perfdata/monitor/protocol/rmi/RemoteMonitoredVm.java+298−0
@@ -0,0 +1,298 @@
1+/*
2+ * Copyright (c) 2004, 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+
26+package sun.jvmstat.perfdata.monitor.protocol.rmi;
27+
28+import sun.jvmstat.monitor.*;
29+import sun.jvmstat.monitor.event.*;
30+import sun.jvmstat.monitor.remote.*;
31+import sun.jvmstat.perfdata.monitor.*;
32+import java.lang.reflect.*;
33+import java.util.*;
34+import java.io.*;
35+import java.nio.ByteBuffer;
36+import java.rmi.*;
37+
38+/**
39+ * Concrete implementation of the AbstractMonitoredVm class for the
40+ * <em>rmi:</em> protocol for the HotSpot PerfData monitoring implementation.
41+ * <p>
42+ * This class provides the ability to acquire to the instrumentation buffer
43+ * of a live, remote target Java Virtual Machine through an RMI server.
44+ *
45+ * @author Brian Doherty
46+ * @since 1.5
47+ */
48+public class RemoteMonitoredVm extends AbstractMonitoredVm {
49+
50+ private ArrayList<VmListener> listeners;
51+ private NotifierTask notifierTask;
52+ private SamplerTask samplerTask;
53+ private Timer timer;
54+
55+ private RemoteVm rvm;
56+ private ByteBuffer updateBuffer;
57+
58+ /**
59+ * Create a RemoteMonitoredVm instance.
60+ *
61+ * @param rvm the proxy to the remote MonitoredVm instance.
62+ * @param vmid the vm identifier specifying the remot target JVM
63+ * @param timer the timer used to run polling tasks
64+ * @param interval the sampling interval
65+ */
66+ public RemoteMonitoredVm(RemoteVm rvm, VmIdentifier vmid,
67+ Timer timer, int interval)
68+ throws MonitorException {
69+ super(vmid, interval);
70+ this.rvm = rvm;
71+ pdb = new PerfDataBuffer(rvm, vmid.getLocalVmId());
72+ this.listeners = new ArrayList<VmListener>();
73+ this.timer = timer;
74+ }
75+
76+ /**
77+ * Method to attach to the remote MonitoredVm.
78+ */
79+ public void attach() throws MonitorException {
80+ updateBuffer = pdb.getByteBuffer().duplicate();
81+
82+ // if continuous sampling is requested, register with the sampler thread
83+ if (interval > 0) {
84+ samplerTask = new SamplerTask();
85+ timer.schedule(samplerTask, 0, interval);
86+ }
87+ }
88+
89+ /**
90+ * {@inheritDoc}
91+ */
92+ public void detach() {
93+ try {
94+ if (interval > 0) {
95+ if (samplerTask != null) {
96+ samplerTask.cancel();
97+ samplerTask = null;
98+ }
99+ if (notifierTask != null) {
100+ notifierTask.cancel();
101+ notifierTask = null;
102+ }
103+ sample();
104+ }
105+ } catch (RemoteException e) {
106+ // XXX: - use logging api? throw an exception instead?
107+ System.err.println("Could not read data for remote JVM " + vmid);
108+ e.printStackTrace();
109+
110+ } finally {
111+ super.detach();
112+ }
113+ }
114+
115+ /**
116+ * Get a copy of the remote instrumentation buffer.
117+ *<p>
118+ * The data in the remote instrumentation buffer is copied into
119+ * a local byte buffer.
120+ *
121+ * @throws RemoteException Thrown on any communications errors with
122+ * the remote system.
123+ */
124+ public void sample() throws RemoteException {
125+ assert updateBuffer != null;
126+ ((PerfDataBuffer)pdb).sample(updateBuffer);
127+ }
128+
129+ /**
130+ * Get the proxy to the remote MonitoredVm.
131+ *
132+ * @return RemoteVm - the proxy to the remote MonitoredVm.
133+ */
134+ public RemoteVm getRemoteVm() {
135+ return rvm;
136+ }
137+
138+ /**
139+ * {@inheritDoc}
140+ */
141+ public void addVmListener(VmListener l) {
142+ synchronized(listeners) {
143+ listeners.add(l);
144+ if (notifierTask == null) {
145+ notifierTask = new NotifierTask();
146+ timer.schedule(notifierTask, 0, interval);
147+ }
148+ }
149+ }
150+
151+ /**
152+ * {@inheritDoc}
153+ */
154+ public void removeVmListener(VmListener l) {
155+ synchronized(listeners) {
156+ listeners.remove(l);
157+ if (listeners.isEmpty() && (notifierTask != null)) {
158+ notifierTask.cancel();
159+ notifierTask = null;
160+ }
161+ }
162+ }
163+
164+ /**
165+ * {@inheritDoc}
166+ */
167+ public void setInterval(int newInterval) {
168+ synchronized(listeners) {
169+ if (newInterval == interval) {
170+ return;
171+ }
172+
173+ int oldInterval = interval;
174+ super.setInterval(newInterval);
175+
176+ if (samplerTask != null) {
177+ samplerTask.cancel();
178+ SamplerTask oldSamplerTask = samplerTask;
179+ samplerTask = new SamplerTask();
180+ CountedTimerTaskUtils.reschedule(timer, oldSamplerTask,
181+ samplerTask, oldInterval,
182+ newInterval);
183+ }
184+ if (notifierTask != null) {
185+ notifierTask.cancel();
186+ NotifierTask oldNotifierTask = notifierTask;
187+ notifierTask = new NotifierTask();
188+ CountedTimerTaskUtils.reschedule(timer, oldNotifierTask,
189+ notifierTask, oldInterval,
190+ newInterval);
191+ }
192+ }
193+ }
194+
195+ /**
196+ * Fire MonitoredVmStructureChanged events.
197+ *
198+ * @param inserted List of Monitor objects inserted.
199+ * @param removed List of Monitor objects removed.
200+ */
201+ void fireMonitorStatusChangedEvents(List inserted, List removed) {
202+ ArrayList registered = null;
203+ MonitorStatusChangeEvent ev = null;
204+
205+ synchronized(listeners) {
206+ registered = (ArrayList)listeners.clone();
207+ }
208+
209+ for (Iterator i = registered.iterator(); i.hasNext(); /* empty */) {
210+ VmListener l = (VmListener)i.next();
211+ if (ev == null) {
212+ ev = new MonitorStatusChangeEvent(this, inserted, removed);
213+ }
214+ l.monitorStatusChanged(ev);
215+ }
216+ }
217+
218+ /**
219+ * Fire MonitoredVmStructureChanged events.
220+ */
221+ void fireMonitorsUpdatedEvents() {
222+ ArrayList registered = null;
223+ VmEvent ev = null;
224+
225+ synchronized(listeners) {
226+ registered = (ArrayList)listeners.clone();
227+ }
228+
229+ for (Iterator i = registered.iterator(); i.hasNext(); /* empty */) {
230+ VmListener l = (VmListener)i.next();
231+ if (ev == null) {
232+ ev = new VmEvent(this);
233+ }
234+ l.monitorsUpdated(ev);
235+ }
236+ }
237+
238+ /*
239+ * Timer Tasks. There are two separate timer tasks here. The SamplerTask
240+ * is active whenever we are attached to the remote JVM with a periodic
241+ * sampling interval > 0. The NotifierTask is only active if a VmListener
242+ * has registered with this RemoteMonitoredVm instance. Also, in the future
243+ * we may want to run these tasks at different intervals. Currently,
244+ * they run at the same interval and some significant work may
245+ * need to be done to complete the separation of these two intervals.
246+ */
247+
248+ /**
249+ * Class to periodically check the state of the defined monitors
250+ * for the remote MonitoredVm instance and to notify listeners of
251+ * any detected changes.
252+ */
253+ private class NotifierTask extends CountedTimerTask {
254+ public void run() {
255+ super.run();
256+ try {
257+ MonitorStatus status = getMonitorStatus();
258+
259+ List inserted = status.getInserted();
260+ List removed = status.getRemoved();
261+
262+ if (!inserted.isEmpty() || !removed.isEmpty()) {
263+ fireMonitorStatusChangedEvents(inserted, removed);
264+ }
265+ } catch (MonitorException e) {
266+ // XXX: use logging api? fire disconnect events? mark errored?
267+ // fireDisconnectedEvents();
268+ System.err.println("Exception updating monitors for "
269+ + getVmIdentifier());
270+ e.printStackTrace();
271+ // XXX: should we cancle the notifierTask here?
272+ // this.cancel();
273+ }
274+ }
275+ }
276+
277+ /**
278+ * Class to periodically sample the remote instrumentation byte buffer
279+ * and refresh the local copy. Registered listeners are notified of
280+ * the completion of a sampling event.
281+ */
282+ private class SamplerTask extends CountedTimerTask {
283+ public void run() {
284+ super.run();
285+ try {
286+ sample();
287+ fireMonitorsUpdatedEvents();
288+
289+ } catch (RemoteException e) {
290+ // XXX: use logging api, mark vm as errored.
291+ System.err.println("Exception taking sample for "
292+ + getVmIdentifier());
293+ e.printStackTrace();
294+ this.cancel();
295+ }
296+ }
297+ }
298+}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t