001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: * The Original Software is NetBeans. The Initial Developer of the Original
026: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
027: * Microsystems, Inc. All Rights Reserved.
028: *
029: * If you wish your version of this file to be governed by only the CDDL
030: * or only the GPL Version 2, indicate your decision by adding
031: * "[Contributor] elects to include this software in this distribution
032: * under the [CDDL or GPL Version 2] license." If you do not indicate a
033: * single choice of license, a recipient has the option to distribute
034: * your version of this file under either the CDDL, the GPL Version 2 or
035: * to extend the choice of license to its licensees as provided above.
036: * However, if you add GPL Version 2 code and therefore, elected the GPL
037: * Version 2 license, then the option applies only if the new code is
038: * made subject to such option by the copyright holder.
039: */
040:
041: package org.netbeans.lib.profiler.results.monitor;
042:
043: import org.netbeans.lib.profiler.client.MonitoredData;
044: import org.netbeans.lib.profiler.results.DataManager;
045:
046: /**
047: * A class that holds telemetry data about the target VM for a single profiling
048: * session. It consumes/processes data obtained from the server via the
049: * MonitoredData class. A listener is provided for those who want to be notified
050: * about newly arrived data.
051: *
052: * @author Ian Formanek
053: * @author Jiri Sedlacek
054: */
055: public class VMTelemetryDataManager extends DataManager {
056: //~ Instance fields ----------------------------------------------------------------------------------------------------------
057:
058: public long[] freeMemory;
059: public long[] gcFinishs;
060: public long[] gcStarts;
061: public long[] lastGCPauseInMS;
062: public long[] loadedClassesCount;
063: public long[] nSurvivingGenerations;
064: public long[] nSystemThreads;
065: public long[] nTotalThreads;
066: public long[] nUserThreads;
067: public long[] relativeGCTimeInPerMil;
068: public long[] timeStamps;
069: public long[] totalMemory;
070: public long[] usedMemory;
071: public long maxHeapSize = Long.MAX_VALUE; // value of Xmx, constant within one profiling session
072:
073: // --- Data storage ----------------------------------------------------------
074: private MonitoredData lastData = null; // last data processed
075:
076: // --- Arrays extending policy -----------------------------------------------
077: private int arrayBufferSize;
078: private int currentArraysSize;
079: private int currentGCArraysSize;
080: private int gcItemCount;
081: private int itemCount;
082:
083: //~ Constructors -------------------------------------------------------------------------------------------------------------
084:
085: // --- Constructors ----------------------------------------------------------
086:
087: /**
088: * Creates a new instance of VMTelemetryDataManager
089: */
090: public VMTelemetryDataManager() {
091: this (50);
092: }
093:
094: /**
095: * Creates a new instance of VMTelemetryDataManager
096: */
097: public VMTelemetryDataManager(int arrayBufferSize) {
098: this .arrayBufferSize = arrayBufferSize;
099: reset();
100: }
101:
102: //~ Methods ------------------------------------------------------------------------------------------------------------------
103:
104: public synchronized void setArrayBufferSize(int arrayBufferSize) {
105: this .arrayBufferSize = arrayBufferSize;
106: }
107:
108: public synchronized int getArrayBufferSize() {
109: return arrayBufferSize;
110: }
111:
112: public synchronized int getGCItemCount() {
113: return gcItemCount;
114: }
115:
116: // --- Getters / setters -----------------------------------------------------
117: public synchronized int getItemCount() {
118: return itemCount;
119: }
120:
121: public synchronized MonitoredData getLastData() {
122: return lastData;
123: }
124:
125: // --- Public runtime API ----------------------------------------------------
126: public synchronized void processData(MonitoredData data) {
127: addValuesInternal(data.getTimestamp(), data.getFreeMemory(),
128: data.getTotalMemory(), data.getNUserThreads(), data
129: .getNSystemThreads(), data
130: .getNSurvivingGenerations(), data
131: .getRelativeGCTimeInPerMil(), data
132: .getLastGCPauseInMS(), data
133: .getLoadedClassesCount(), data.getGCStarts(),
134: data.getGCFinishs());
135: lastData = data;
136: }
137:
138: public synchronized void reset() {
139: lastData = null;
140:
141: itemCount = 0;
142: gcItemCount = 0;
143:
144: timeStamps = new long[arrayBufferSize];
145:
146: freeMemory = new long[arrayBufferSize];
147:
148: totalMemory = new long[arrayBufferSize];
149:
150: usedMemory = new long[arrayBufferSize];
151:
152: nUserThreads = new long[arrayBufferSize];
153:
154: nSystemThreads = new long[arrayBufferSize];
155:
156: nTotalThreads = new long[arrayBufferSize];
157:
158: nSurvivingGenerations = new long[arrayBufferSize];
159:
160: relativeGCTimeInPerMil = new long[arrayBufferSize];
161:
162: lastGCPauseInMS = new long[arrayBufferSize];
163:
164: loadedClassesCount = new long[arrayBufferSize];
165:
166: currentArraysSize = arrayBufferSize;
167: currentGCArraysSize = arrayBufferSize;
168:
169: gcStarts = new long[arrayBufferSize];
170: gcFinishs = new long[arrayBufferSize];
171:
172: fireDataReset();
173: }
174:
175: // --- Data storage management -----------------------------------------------
176: private void addValuesInternal(long timeStamp, long freeMemory,
177: long totalMemory, long nUserThreads, long nSystemThreads,
178: long nSurvivingGenerations, long relativeGCTimeInPerMil,
179: long lastGCPauseInMS, long loadedClassesCount,
180: long[] gcStarts, long[] gcFinishs) {
181: checkArraysSize();
182:
183: this .timeStamps[itemCount] = timeStamp;
184: this .freeMemory[itemCount] = freeMemory;
185: this .totalMemory[itemCount] = totalMemory;
186: this .usedMemory[itemCount] = totalMemory - freeMemory;
187: this .nUserThreads[itemCount] = nUserThreads;
188: this .nSystemThreads[itemCount] = nSystemThreads;
189: this .nTotalThreads[itemCount] = nSystemThreads + nUserThreads;
190: this .nSurvivingGenerations[itemCount] = nSurvivingGenerations;
191:
192: // TODO: should be one tenth (relativeGCTimeInPerMil / 10)
193: this .relativeGCTimeInPerMil[itemCount] = relativeGCTimeInPerMil;
194: this .lastGCPauseInMS[itemCount] = lastGCPauseInMS;
195: this .loadedClassesCount[itemCount] = loadedClassesCount;
196:
197: itemCount++;
198:
199: int gcDataCount = Math.min(gcStarts.length, gcFinishs.length);
200:
201: for (int i = 0; i < gcDataCount; i++) {
202: this .gcStarts[gcItemCount] = gcStarts[i];
203: this .gcFinishs[gcItemCount] = gcFinishs[i];
204: gcItemCount++;
205: checkArraysSize();
206: }
207:
208: fireDataChanged();
209: }
210:
211: private void checkArraysSize() {
212: // array extension is needed
213: if (currentArraysSize == itemCount) {
214: timeStamps = extendArray(timeStamps, arrayBufferSize);
215: freeMemory = extendArray(freeMemory, arrayBufferSize);
216: totalMemory = extendArray(totalMemory, arrayBufferSize);
217: usedMemory = extendArray(usedMemory, arrayBufferSize);
218: nUserThreads = extendArray(nUserThreads, arrayBufferSize);
219: nSystemThreads = extendArray(nSystemThreads,
220: arrayBufferSize);
221: nTotalThreads = extendArray(nTotalThreads, arrayBufferSize);
222: nSurvivingGenerations = extendArray(nSurvivingGenerations,
223: arrayBufferSize);
224: relativeGCTimeInPerMil = extendArray(
225: relativeGCTimeInPerMil, arrayBufferSize);
226: lastGCPauseInMS = extendArray(lastGCPauseInMS,
227: arrayBufferSize);
228: loadedClassesCount = extendArray(loadedClassesCount,
229: arrayBufferSize);
230:
231: // update current array size
232: currentArraysSize += arrayBufferSize;
233: }
234:
235: if (currentGCArraysSize == gcItemCount) {
236: gcStarts = extendArray(gcStarts, arrayBufferSize);
237: gcFinishs = extendArray(gcFinishs, arrayBufferSize);
238:
239: currentGCArraysSize += arrayBufferSize;
240: }
241: }
242:
243: // extends 1-dimensional array
244: private static long[] extendArray(long[] array, int extraLength) {
245: int originalLength = array.length;
246: long[] newArray = new long[originalLength + extraLength];
247: System.arraycopy(array, 0, newArray, 0, originalLength);
248:
249: return newArray;
250: }
251: }
|