001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026:
027: package view;
028:
029: import java.awt.*;
030: import java.awt.event.*;
031: import java.util.Iterator;
032: import javax.swing.*;
033: import com.sun.cldchi.tools.memoryprofiler.data.*;
034:
035: public class ViewMemoryPanel extends JComponent {
036: MPDataProvider _data_provider;
037:
038: //paramenters of view
039: private static final int _hor_bloc_number = 100;
040: private static final int _ver_bloc_number = 20;
041: private static final int _block_number = _hor_bloc_number
042: * _ver_bloc_number;
043: private int _block_height = -1;
044: private int _block_width = -1;
045:
046: //the arrays are used for temperature calculation
047: private double[] _block_utilization_count = new double[_block_number];
048:
049: private JavaClass selected_class = null;
050: private int[] _block_object_count = new int[_block_number];
051:
052: //various addresses at start_offset and at end_offset
053: private int _inline_allocation_top = -1;
054: private int _old_generation_end = -1;
055: private int _heap_start = -1;
056: private int _heap_top = -1;
057:
058: public ViewMemoryPanel(MPDataProvider data_provider) {
059: _data_provider = data_provider;
060: setMinimumSize(new Dimension(600, 300));
061: addMouseListener(new ViewMemoryMouseListener());
062: }
063:
064: public void set_selected_class_id(JavaClass jc) {
065: selected_class = jc;
066: }
067:
068: public void update() {
069: _inline_allocation_top = _data_provider.get_allocation_top();
070: _old_generation_end = _data_provider.get_old_gen_end();
071: _heap_start = _data_provider.get_heap_start();
072: _heap_top = _data_provider.get_heap_top();
073: update_block_utilization();
074: repaint();
075: }
076:
077: public void paint(Graphics g) {
078: Dimension size = getSize();
079: _block_width = (size.width - 150) / _hor_bloc_number;
080: _block_height = size.height / _ver_bloc_number;
081: prepare_blocks();
082: for (int i = 0; i < _block_number; i++) {
083: draw_block(g, i);
084: }
085: draw_inline_allocations(g);
086: draw_old_generation_end(g);
087: draw_agenda(g);
088: }
089:
090: public void draw_agenda(Graphics g) {
091: int x = _block_width * _hor_bloc_number + 10;
092: int y = 1;
093: draw_block_symbol(g, x, y, 100, 0);
094: draw_allocation_top_symbol(g, x, y, false);
095: g.setColor(Color.BLACK);
096: g.drawString("_inline_allocation_top block", x + 2
097: * _block_width, y + _block_height);
098:
099: y += 2 * _block_height;
100: draw_block_symbol(g, x, y, 100, 0);
101: draw_old_generation_end_symbol(g, x, y, false);
102: g.setColor(Color.BLACK);
103: g.drawString("_old_generation_end block", x + 2 * _block_width,
104: y + _block_height);
105:
106: y += 2 * _block_height;
107: draw_block_symbol(g, x, y, 1, 0);
108: g.setColor(Color.BLACK);
109: g.drawString("block with 100% utilization", x + 2
110: * _block_width, y + _block_height);
111:
112: y += 2 * _block_height;
113: draw_block_symbol(g, x, y, 0.5, 0);
114: g.setColor(Color.BLACK);
115: g.drawString("block with 50% utilization",
116: x + 2 * _block_width, y + _block_height);
117:
118: y += 2 * _block_height;
119: draw_block_symbol(g, x, y, 0, 0);
120: g.setColor(Color.BLACK);
121: g.drawString("block with 0% utilization", x + 2 * _block_width,
122: y + _block_height);
123:
124: y += 2 * _block_height;
125: draw_block_symbol(g, x, y, 100, 1);
126: g.setColor(Color.BLACK);
127: g.drawString("block with object ", x + 2 * _block_width, y
128: + _block_height / 2);
129: g.drawString("of selected type", x + 2 * _block_width, y
130: + (3 * _block_height) / 2);
131:
132: y += 2 * _block_height;
133: draw_block_symbol(g, x, y, 100, 110);
134: g.setColor(Color.BLACK);
135: g.drawString("block with many objects ", x + 2 * _block_width,
136: y + _block_height / 2);
137: g.drawString("of selected type", x + 2 * _block_width, y
138: + (3 * _block_height) / 2);
139:
140: }
141:
142: public Dimension getPreferredSize() {
143: return new Dimension(900, 300);
144: }
145:
146: private void draw_old_generation_end(Graphics g) {
147: int i = get_block_number(_old_generation_end);
148: int x = _block_width * (i % _hor_bloc_number);
149: int y = _block_height * (i / _hor_bloc_number);
150: draw_old_generation_end_symbol(g, x, y, false);
151: }
152:
153: private void draw_inline_allocations(Graphics g) {
154: int i = get_block_number(_inline_allocation_top);
155: int x = _block_width * (i % _hor_bloc_number);
156: int y = _block_height * (i / _hor_bloc_number);
157: draw_allocation_top_symbol(g, x, y, false);
158: }
159:
160: private void draw_block(Graphics g, int i) {
161: int x = _block_width * (i % _hor_bloc_number);
162: int y = _block_height * (i / _hor_bloc_number);
163: draw_block_symbol(g, x, y, _block_utilization_count[i],
164: _block_object_count[i]);
165: }
166:
167: private void prepare_blocks() {
168: for (int i = 0; i < _block_number; i++) {
169: _block_object_count[i] = 0;
170: }
171:
172: JavaObject[] objects = _data_provider
173: .getObjectsOfClass(selected_class);
174: for (int i = 0; i < objects.length; i++) {
175: int address = objects[i].address;
176: int block_number = get_block_number(address);
177: _block_object_count[block_number]++;
178: }
179: }
180:
181: private void update_block_utilization() {
182: for (int i = 0; i < _block_number; i++) {
183: int start = get_address_by_block_num(i);
184: int end = get_address_by_block_num(i + 1);
185: JavaObject[] objects = _data_provider
186: .getObjectsFromTheAddresses(start, end);
187: int full_size = 0;
188: int real_size = 0;
189: for (int j = 0; j < objects.length; j++) {
190: full_size += objects[j].size;
191: if (objects[j].alive())
192: real_size += objects[j].size;
193: }
194: if (full_size == 0) {
195: _block_utilization_count[i] = 1;
196: } else {
197: _block_utilization_count[i] = ((double) real_size)
198: / full_size;
199: }
200: }
201:
202: }
203:
204: private int get_block_number(int address) {
205: if (address < _heap_start || address > _heap_top) {
206: return -1;
207: }
208: double tmp = ((double) (address - _heap_start))
209: / (_heap_top - _heap_start);
210: int res = (int) (tmp * _block_number);
211: return res;
212: }
213:
214: private int get_block_num_by_mouse_event(MouseEvent e) {
215: return e.getY() / _block_height * _hor_bloc_number + e.getX()
216: / _block_width;
217: }
218:
219: private int get_address_by_block_num(int block_num) {
220: return (int) (_heap_start + (_heap_top - _heap_start)
221: * (((double) block_num) / _block_number));
222: }
223:
224: private void draw_allocation_top_symbol(Graphics g, int x, int y,
225: boolean gc) {
226: g.setColor(new Color(164, 255, 64));
227: g.drawRect(x, y, 1, _block_height);
228: }
229:
230: private void draw_old_generation_end_symbol(Graphics g, int x,
231: int y, boolean gc) {
232: g.setColor(new Color(64, 64, 255));
233: g.drawRect(x, y, 1, _block_height);
234: }
235:
236: private void draw_block_symbol(Graphics g, int x, int y,
237: double utilization, int objects_num) {
238: int util = (int) (255 * Math.sqrt(1 - utilization));
239: g.setColor(new Color(util, 0, 0));
240: g.fillRect(x + 1, y + 1, _block_width - 1, _block_height - 1);
241: g.setColor(new Color(255, 255, 0));
242: int radius = 0;
243: if (objects_num > 0)
244: radius = 1;
245: if (objects_num > 10)
246: radius = 2;
247: if (objects_num > 100) {
248: radius = 3;
249: x--;
250: }
251: g.fillOval(x + _block_width / 2, y + _block_height / 2, radius,
252: radius);
253: }
254:
255: public boolean contains(int x, int y) {
256: if (!super .contains(x, y))
257: return false;
258: if (y > _block_height * _ver_bloc_number
259: || x > _block_width * _hor_bloc_number)
260: return false;
261: int blockNum = (y / _block_height) * _hor_bloc_number + x
262: / _block_width;
263: int address = get_address_by_block_num(blockNum);
264: setToolTipText("0x" + Integer.toHexString(address));
265: return true;
266: }
267:
268: class ViewMemoryMouseListener extends MouseAdapter {
269: public void mouseClicked(MouseEvent e) {
270: if (e.getButton() != MouseEvent.BUTTON1) {
271: return;
272: }
273: int start = get_address_by_block_num(get_block_num_by_mouse_event(e));
274: int end = get_address_by_block_num(get_block_num_by_mouse_event(e) + 1);
275: String title = "Objects from " + Integer.toHexString(start)
276: + " to " + Integer.toHexString(end);
277: ViewRootPathDialog.showDialog(ViewMemoryPanel.this,
278: _data_provider.getObjectsFromTheAddresses(start,
279: end), title, _data_provider);
280: }
281: }
282: }
|