1
2
3
4
5
6
7
8
9
10
11
12
13
14 package net.sf.madmap;
15
16 import java.io.*;
17 import java.util.*;
18 import java.util.concurrent.*;
19 import java.util.concurrent.atomic.AtomicInteger;
20 import java.math.*;
21 import java.lang.management.*;
22 import javax.management.*;
23 import javax.swing.JOptionPane;
24
25
26
27
28
29
30
31 public class HprofReader implements IHprofReader, HprofReaderMBean {
32
33 ILogger _logger;
34
35 static String objStart = new String( "O" );
36 static String arrStart = new String( "A" );
37 static String clsStart = new String( "CL" );
38
39
40 AtomicInteger _objects = new AtomicInteger(0);
41 AtomicInteger _arrays = new AtomicInteger(0);
42 AtomicInteger _classes = new AtomicInteger(0);
43 public int getCurrentObjects() { return _objects.get(); }
44 public int getCurrentArrays() { return _arrays.get(); }
45 public int getCurrentClasses() { return _classes.get(); }
46 public String getReaderName() { return "HprofReader:workers=" + MadmapMain.concurrency(); }
47
48 public HprofReader() { }
49
50 public void setLogger( ILogger logger ) { _logger = logger; }
51
52 public static FileInputStream openHprofFile(String fileName)
53 {
54 FileInputStream fis;
55
56 try {
57 fis = new FileInputStream( fileName );
58 return fis;
59 } catch ( Exception ie ) {
60 System. out. println ( "Error opening file : Caught " + ie );
61 ie.printStackTrace();
62 }
63 return null;
64 }
65
66 public void parse( Madmap owner, String fileName) {
67 long fileSize = 0;
68
69 try {
70 File fi = new File( fileName );
71 fileSize = fi.length();
72 if ( MadmapMain.verbose() ) {
73 _logger.myLog( owner.getWindow(), "Total file length of " + fileName + " is " + fileSize );
74 }
75 } catch ( Exception ie ) {
76 System. out. println ( "Error opening file : Caught " + ie );
77 ie.printStackTrace();
78 }
79
80 long stripeWidth = fileSize / MadmapMain.concurrency();
81 if ( MadmapMain.verbose() ) {
82 _logger.myLog( owner.getWindow(), "Stripe width is " + stripeWidth );
83 _logger.myLog( owner.getWindow(), "Going to run with " + MadmapMain.concurrency() + ( MadmapMain.concurrency() == 1 ? " thread" : " threads" ));
84 }
85
86 try {
87 ExecutorService tpe = Executors.newFixedThreadPool( MadmapMain.concurrency() );
88 for ( int i = 0; i < MadmapMain.concurrency(); i ++ ) {
89 tpe.execute( new Worker( owner, i, openHprofFile(fileName), i * stripeWidth, stripeWidth ) );
90 }
91
92 tpe.shutdown();
93 tpe.awaitTermination(9999, TimeUnit.SECONDS);
94 } catch ( InterruptedException ie ) {
95 System. out. println ( "*** InterruptedException happened 2" );
96 }
97 }
98
99
100
101
102
103
104
105 private class Worker implements Runnable {
106
107 Madmap _owner = null;
108
109 ConcurrentHashMap<HprofHeapAllocation,HprofHeapAllocation> _heap_objects_table = null;
110 ConcurrentHashMap _stack_trace_table = null;
111 ConcurrentHashMap _threads_list = null;
112 Vector _roots_list = null;
113 ConcurrentHashMap _class_list = null;
114
115 boolean _verbose = false;
116
117 public void dumpObjectsTable() { _heap_objects_table = null; }
118
119 public ConcurrentHashMap getStackTraces() { return _stack_trace_table; }
120 public ConcurrentHashMap getThreads() { return _threads_list; }
121 public Vector getRoots() { return _roots_list; }
122 public ConcurrentHashMap getClasses() { return _class_list; }
123
124 FileInputStream _fis;
125 LineNumberReader _bfr;
126 int _readerId;
127 long _startOffset;
128 long _estimatedCompletionLine;
129
130 String _pushed_string = null;
131 int _linesSeen = 0;
132 long _startTime = 0;
133
134 org.apache.regexp.RE thread_start_re = new org.apache.regexp.RE( "THREAD START .*" );
135 org.apache.regexp.RE thread_end_re = new org.apache.regexp.RE( "THREAD END .*" );
136 org.apache.regexp.RE stack_trace_re = new org.apache.regexp.RE( "^TRACE ([0-9]*):" );
137 org.apache.regexp.RE obj_start_re = new org.apache.regexp.RE( "^OBJ .*" );
138 org.apache.regexp.RE array_start_re = new org.apache.regexp.RE( "^ARR .*" );
139
140 org.apache.regexp.RE thread_start_obj = new org.apache.regexp.RE( "obj=([0-9A-Za-z]*),.*" );
141 org.apache.regexp.RE thread_start_id = new org.apache.regexp.RE( "id = ([0-9 ]*),.*" );
142 org.apache.regexp.RE thread_start_name = new org.apache.regexp.RE( "name=(.*),.*" );
143 org.apache.regexp.RE thread_start_group = new org.apache.regexp.RE( "group=(\".*\")" );
144
145 org.apache.regexp.RE _stack_trace_title_re = new org.apache.regexp.RE( "^TRACE ([0-9]*):" );
146 org.apache.regexp.RE _stack_trace_item_re = new org.apache.regexp.RE( "\t(.*)" );
147
148 org.apache.regexp.RE _heap_dump_begin_re = new org.apache.regexp.RE( "^HEAP DUMP BEGIN " );
149 org.apache.regexp.RE _heap_dump_objects_re = new org.apache.regexp.RE( "([0-9]*) objects, " );
150 org.apache.regexp.RE _heap_dump_bytes_re = new org.apache.regexp.RE( ", ([0-9]*) bytes" );
151 org.apache.regexp.RE _heap_dump_end_re = new org.apache.regexp.RE( "^HEAP DUMP END" );
152
153 org.apache.regexp.RE _root_begin_re = new org.apache.regexp.RE( "^ROOT ([0-9A-Za-z]*) " );
154 org.apache.regexp.RE _root_kind_re = new org.apache.regexp.RE( "kind=([0-9A-Za-z -<>]*), " );
155 org.apache.regexp.RE _root_kind_unknown_re = new org.apache.regexp.RE( "kind=<unknown>" );
156 org.apache.regexp.RE _root_kind_busymon_re = new org.apache.regexp.RE( "kind=<busy monitor>" );
157 org.apache.regexp.RE _root_classname_re = new org.apache.regexp.RE( " name=([0-9A-Za-z.$]*)" );
158 org.apache.regexp.RE _root_id_re = new org.apache.regexp.RE( "id=(.*), " );
159 org.apache.regexp.RE _root_trace_re = new org.apache.regexp.RE( "trace= ([0-9]*)" );
160
161 org.apache.regexp.RE _obj_all_re = new org.apache.regexp.RE( "^OBJ ([0-9A-Za-z]*) [:punct:]sz=([0-9]*), trace=([0-9]*), class=([0-9A-Za-z_.$]*)@([0-9a-f]*)" );
162 org.apache.regexp.RE _obj_member_both_re = new org.apache.regexp.RE( "^\t([0-9A-Za-z_$]*)[ \t]+([0-9A-Za-z_]*)" );
163
164
165 org.apache.regexp.RE _arr_type_both_re = new org.apache.regexp.RE( "elem type=(.*)@([0-9A-Za-z]*)" );
166
167
168 org.apache.regexp.RE _arr_type_re2 = new org.apache.regexp.RE( "elem type=(.*)[:punct:]" );
169
170 org.apache.regexp.RE _arr_elem_both_re = new org.apache.regexp.RE( "^\t([:punct:][0-9]+[:punct:])[\t ]+([0-9A-Za-z]+)" );
171
172
173 org.apache.regexp.RE _arr_all_re = new org.apache.regexp.RE( "^ARR ([0-9A-Za-z]*) [:punct:]sz=([0-9]*), trace=([0-9]*), nelems=([0-9A-Za-z]*), " );
174
175 org.apache.regexp.RE _cls_super_re = new org.apache.regexp.RE( "^\tsuper[ \t]+([0-9A-Za-z]*)" );
176 org.apache.regexp.RE _cls_loader_re = new org.apache.regexp.RE( "^\tloader[ \t]+([0-9A-Za-z]*)" );
177 org.apache.regexp.RE _cls_static_name_re = new org.apache.regexp.RE( "^\tstatic ([0-9_A-Za-z.$]*)" );
178 org.apache.regexp.RE _cls_static_addr_re = new org.apache.regexp.RE( "^\tstatic [0-9_A-Za-z.$]+[\t]+([0-9a-f]*)" );
179
180 org.apache.regexp.RE _cls_all_re = new org.apache.regexp.RE( "^CLS ([0-9A-Za-z]*) [:punct:]name=(.*), trace=([0-9]*)" );
181
182
183 public void run() {
184
185 int ln = 0;
186
187 _startTime = System.currentTimeMillis();
188 System. out. println ( "Moving to start position " + _startOffset );
189
190 try {
191 InputStreamReader isr;
192 _fis.skip( _startOffset );
193
194 isr = new InputStreamReader( _fis );
195 _bfr = new LineNumberReader( isr );
196
197 } catch ( IOException ioe ) {
198 System. out. println ( "Exception while seeking to file start position..." );
199 ioe.printStackTrace();
200 }
201
202 System. out. println ( "Loading file from start position " + _startOffset );
203
204 readAndProcessLines(-1);
205 long endMillis = System.currentTimeMillis();
206
207 System. out. println ( "Done Loading stripe from start position: " + _startOffset );
208 System. out. println ( "Elapsed time: " + elapsedTime());
209 }
210
211
212
213
214
215
216
217
218
219 public Worker(Madmap owner, int id, FileInputStream rdr, long startPos, long stripeWidth) {
220 _startOffset = startPos;
221 _fis = rdr;
222 _owner = owner;
223 _readerId = id;
224
225
226 _estimatedCompletionLine = stripeWidth / 35;
227 if (( ! MadmapMain.noGUI()) && ( _readerId == 0 )) {
228 _owner.getWindow().getProgressBar().setMaximum((int)_estimatedCompletionLine);
229 _owner.getWindow().getLabelForProgressBar().setText("Loading File");
230 }
231 System. out. println ( "HprofReader reader id = " + _readerId + " _estimatedCompletionLine " + _estimatedCompletionLine );
232
233 _heap_objects_table = owner.getObjects();
234 _stack_trace_table = owner.getStackTraces();
235 _threads_list = owner.getThreads();
236 _roots_list = owner.getRoots();
237 _class_list = owner.getClasses();
238 }
239
240 long[] longArrayListtoLongArray( ArrayList in ) {
241 long[] out = new long[ in.size() ];
242 for ( int i = 0; i < out.length; i++ ) {
243 out[ i ] = ((Long) in.get( i )).longValue();
244 }
245 return out;
246 }
247
248
249 public String matchAndGet( org.apache.regexp.RE active, String s) {
250 if ( active.match(s) == true ) {
251 return active.getParen( 1 );
252 } else {
253 return null;
254 }
255 }
256
257 public long convertAddrStringToLong( String s) {
258 return (new BigInteger( s, 16 )).longValue();
259 }
260
261 public void handleClass( String s ) {
262 String objstr = null;
263 String trcstr = null;
264 String clsstr = null;
265 String elem_name = null;
266 String elem_addr = null;
267 String sooper = null;
268 String loader = null;
269 String next = null;
270 ArrayList st_names = new ArrayList();
271 ArrayList st_refs = new ArrayList();
272
273 if ( _cls_all_re.match( s ) ) {
274 objstr = _cls_all_re.getParen( 1 );
275 clsstr = _cls_all_re.getParen( 2 );
276 trcstr = _cls_all_re.getParen( 3 );
277 }
278 clsstr = clsstr.intern();
279
280 int trcId = Integer.parseInt( trcstr, 10 );
281
282 try {
283 next = readNextLine();
284 while (next != null) {
285 if ( _cls_super_re.match( next )) {
286 sooper = _cls_super_re.getParen( 1 );
287 } else if ( _cls_loader_re.match( next )) {
288 loader = _cls_loader_re.getParen( 1 );
289 } else if ( _cls_static_name_re.match( next )) {
290 elem_name = _cls_static_name_re.getParen( 1 );
291 elem_name = elem_name.intern();
292 st_names.add( elem_name );
293 if ( _cls_static_addr_re.match( next ) ) {
294 elem_addr = _cls_static_addr_re.getParen( 1 );
295
296 st_refs.add( convertAddrStringToLong( elem_addr ) );
297 }
298 } else {
299 if (_verbose) {
300 System. out. println( "#### Class unmatched: " + objstr + " " + clsstr);
301 System. out. println( "#### Class unmatched: " + next);
302 }
303 break;
304 }
305 next = readNextLine();
306 }
307 } catch ( Exception e ) {
308 System. out. println ( "handleClass : Caught " + e + " on line : " + s );
309 System. out. println( "#### Class problem: s = " + s);
310 System. out. println( "#### Class problem: sooper = " + sooper);
311 System. out. println( "#### Class problem: loader = " + loader);
312 System. out. println( "#### Class problem: elem_name = " + elem_name);
313 e. printStackTrace();
314 System.exit( -1 );
315 }
316
317 if ( next != null) {
318 pushBack( next );
319 }
320
321
322 long addr = convertAddrStringToLong( objstr );
323
324 long sooper_addr = 0;
325 long loader_addr = 0;
326 if ( sooper != null ) {
327
328 sooper_addr = convertAddrStringToLong( sooper );
329 }
330 if ( loader != null ) {
331
332 loader_addr = convertAddrStringToLong( loader );
333 }
334
335
336 HprofClassElement cls = (HprofClassElement) _class_list.get( new HprofHeapElement(addr) );
337 if ( cls != null ) {
338
339 if ( ! clsstr.equals( cls.className() ) ) {
340 System.out.println( "### Classes are messed up: " + clsstr + " != " + cls.className() );
341 }
342
343 cls.completeClass( clsstr, trcId, sooper_addr, loader_addr, st_names, st_refs );
344 } else {
345 if ( _verbose ) {
346 System. out. println( "#### Adding Class class with no instances: " + clsstr);
347 }
348 cls = new HprofClassElement( addr, clsstr, trcId, sooper_addr, loader_addr, st_names, st_refs );
349 _class_list.put(cls, cls);
350 _classes.incrementAndGet();
351 }
352 }
353
354
355 public int handleArray( String s ) {
356 String objstr = null;
357 String trcstr = null;
358 String szstr = null;
359 String nelemstr = null;
360 String idstr = null;
361 String elem_idx;
362 String elem_addr;
363 String next = null;
364 ArrayList elems = new ArrayList();
365 long cls_addr = 0;
366
367 if ( _arr_all_re.match( s ) ) {
368 objstr = _arr_all_re.getParen( 1 );
369 szstr = _arr_all_re.getParen( 2 );
370 trcstr = _arr_all_re.getParen( 3 );
371 nelemstr = _arr_all_re.getParen( 4 );
372 }
373
374 int trcId = Integer.parseInt( trcstr, 10 );
375
376 String clsstr = null;
377 HprofClassElement k = null;
378
379 if ( _arr_type_both_re.match( s ) ) {
380
381 clsstr = _arr_type_both_re.getParen( 1 );
382 idstr = _arr_type_both_re.getParen( 2 );
383
384 cls_addr = convertAddrStringToLong( idstr );
385
386
387 clsstr = clsstr.intern();
388
389
390 if ( MadmapMain.jdk14_compatible() ) {
391 if (( clsstr.charAt( 0 ) == '[' ) && ( clsstr.charAt( 1 ) != 'L' ) && ( clsstr.charAt( 1 ) != '[' )) {
392 k = Madmap.getFakeArrayClass( clsstr );
393
394 } else {
395
396
397
398
399 k = (HprofClassElement)(_owner.getClasses()).get( new HprofHeapElement(cls_addr) );
400 if ( k == null ) {
401 k = new HprofClassElement( cls_addr, clsstr );
402 _owner.getClasses().put( k, k );
403
404 }
405
406
407
408
409 long arrayKlassAddr = 1 - cls_addr;
410
411
412 HprofClassElement ak = (HprofClassElement)(_owner.getClasses()).get( new HprofHeapElement(arrayKlassAddr) );
413 if ( ak == null ) {
414
415 String arrayKlassName = new String( "[Array type]" + clsstr );
416 arrayKlassName = arrayKlassName.intern();
417 ak = new HprofClassElement( arrayKlassAddr, arrayKlassName );
418 _owner.getClasses().put( ak, ak );
419
420 }
421
422
423 k = ak;
424 }
425 }
426 } else {
427
428 clsstr = matchAndGet( _arr_type_re2, s );
429
430 clsstr = clsstr.intern();
431 k = Madmap.getFakeArrayClass( clsstr );
432 }
433
434 next = readNextLine();
435
436 while ((next != null) && ( next.startsWith( "\t" ))) {
437
438 String fields = next.substring( 1 );
439
440 int len = 0;
441 while ( fields.charAt( len ) != '\t' ) {
442 len++;
443 }
444
445
446 while ( fields.charAt( len ) == '\t' ) {
447 len++;
448 }
449 String faddr = fields.substring( len );
450 elems.add( convertAddrStringToLong( faddr ) );
451
452 next = readNextLine();
453 }
454
455 if ( next != null) {
456 pushBack( next );
457 }
458
459 long addr = convertAddrStringToLong( objstr );
460 long nelems = Long.parseLong( nelemstr, 10 );
461 long size = Long.parseLong( szstr, 10 );
462
463 HprofHeapCollectable testObj = (HprofHeapCollectable) _heap_objects_table.get( new HprofHeapElement(addr) );
464 if ( testObj != null ) {
465 return -1;
466 }
467
468 HprofArrayObject arr = new HprofArrayObject( addr, clsstr, trcId, size, nelems, k, elems );
469 _heap_objects_table.put( arr, arr );
470 _arrays.incrementAndGet();
471 return 0;
472 }
473
474 HprofClassElement findOrCreateClass( String klass, long klass_addr, long size, ArrayList field_names ) {
475
476 assert size != 0 : "size should not be 0" ;
477
478 HprofClassElement k = (HprofClassElement) getClasses().get( new HprofHeapElement(klass_addr) );
479 if ( k == null ) {
480
481 k = new HprofClassElement( klass_addr, klass, size );
482 getClasses().put( k, k );
483 } else {
484 assert k.addr() == klass_addr : "klass addr is wrong" ;
485
486
487
488 if ( k.instanceSize() == 0 ) {
489 k.updateInstanceSize(size);
490 }
491 }
492
493 return k;
494 }
495
496 public int handleObject( String s ) {
497
498 String objstr = null;
499 String trcstr = null;
500 String clsstr = null;
501 String clsaddrstr = null;
502 String szstr = null;
503 String elem = null;
504 String id = null;
505 String next = null;
506 ArrayList elem_ids = new ArrayList();
507 ArrayList elem_names = new ArrayList();
508
509 if ( _obj_all_re.match( s ) ) {
510 objstr = _obj_all_re.getParen( 1 );
511 szstr = _obj_all_re.getParen( 2 );
512 trcstr = _obj_all_re.getParen( 3 );
513 clsstr = _obj_all_re.getParen( 4 );
514 clsaddrstr = _obj_all_re.getParen( 5 );
515 }
516
517 clsstr = clsstr.intern();
518 next = readNextLine();
519 int trcId = Integer.parseInt( trcstr, 10 );
520
521 while ((next != null) && ( next.startsWith( "\t" ))) {
522
523 String fields = next.substring( 1 );
524
525 int len = 0;
526 while ( fields.charAt( len ) != '\t' ) {
527 len++;
528 }
529
530 String fname = fields.substring( 0, len );
531 fname = fname.intern();
532 elem_names.add( fname );
533
534 while ( fields.charAt( len ) == '\t' ) {
535 len++;
536 }
537 String faddr = fields.substring( len );
538 elem_ids.add( convertAddrStringToLong( faddr ) );
539
540 next = readNextLine();
541 }
542
543 if ( next != null) {
544 pushBack( next );
545 }
546
547 if ( clsaddrstr == null ) {
548 System. out. println( "#### Object clsaddrstr is null: " + objstr);
549 }
550
551 long addr = convertAddrStringToLong( objstr );
552
553 HprofHeapCollectable testObj = (HprofHeapCollectable) _heap_objects_table.get( new HprofHeapElement(addr) );
554 if ( testObj != null ) {
555
556
557
558
559
560 return -1;
561 }
562
563 long cls_addr = convertAddrStringToLong( clsaddrstr );
564 long size = Long.parseLong( szstr, 10 );
565
566 if ( ! MadmapMain.getSaveMemberNames() ) {
567 elem_names = null;
568 }
569
570
571 if ( elem_ids.size() == 0 ) {
572 elem_ids = null;
573 elem_names = null;
574 }
575
576
577 HprofClassElement k = findOrCreateClass( clsstr, cls_addr, size, elem_names );
578
579 HprofObject ho = new HprofObject( addr, clsstr, k, size, trcId, elem_names, elem_ids );
580
581 if (( elem_names != null ) && ( elem_names.size() != 0 )) {
582 ho.set_member_name_indexes( k.setNonstaticFieldNames( elem_names ) );
583 }
584
585
586 _heap_objects_table.put( ho, ho );
587 _objects.incrementAndGet();
588 return 0;
589 }
590
591
592 public void handleRoot( String s ) {
593 int i = 0;
594 String objstr = matchAndGet( _root_begin_re, s );
595 String kindstr = matchAndGet( _root_kind_re, s );
596 String idstr = null;
597 String trcstr = null;
598 String classnamestr = null;
599
600 if ( kindstr == null ) {
601 if ( _root_kind_unknown_re.match(s) ) {
602 kindstr = "<unknown>";
603 } else if ( _root_kind_busymon_re.match(s) ) {
604 kindstr = "<busy monitor>";
605 }
606 }
607
608 kindstr = kindstr.intern();
609
610 if ( kindstr.equals("<JNI global ref>") ) {
611 idstr = matchAndGet( _root_id_re, s );
612 trcstr = matchAndGet( _root_trace_re, s );
613 } else if ( kindstr.equals("<unknown>") ) {
614 } else if ( kindstr.equals("<Java stack>") ) {
615 } else if ( kindstr.equals("<thread block>") ) {
616 } else if ( kindstr.equals("<JNI local ref>") ) {
617 } else if ( kindstr.equals("<thread>") ) {
618 } else if ( kindstr.equals("<busy monitor>") ) {
619 } else if ( kindstr.equals("<native stack>") ) {
620
621 } else if ( kindstr.equals("<system class>") ) {
622 classnamestr = matchAndGet( _root_classname_re, s );
623
624 classnamestr = classnamestr.intern();
625 } else {
626 System. out. println( "### unknown root : " + s );
627 }
628
629
630
631 HprofRoot rt = new HprofRoot( convertAddrStringToLong( objstr ), kindstr );
632 _roots_list.add( rt );
633 }
634
635
636 public void handleHeapDumpStart( String s ) {
637 int i = 0;
638 String objstr = matchAndGet( _heap_dump_objects_re, s );
639 String bytestr = matchAndGet( _heap_dump_bytes_re, s );
640
641 System. out. println( "Heap dump objects : " + objstr );
642 System. out. println( "Heap dump bytes : " + bytestr );
643 }
644
645
646 public void handleThreadStart( String s ) {
647 String objstr = matchAndGet( thread_start_obj, s );
648 String idstr = matchAndGet( thread_start_id, s );
649 String namestr = matchAndGet( thread_start_name, s );
650 String grpstr = matchAndGet( thread_start_group, s );
651
652 if ( objstr != null && idstr != null && namestr != null && grpstr != null ) {
653 long addr = convertAddrStringToLong( objstr );
654 int id = Integer.parseInt( idstr, 10 );
655
656 HprofThreadData td = new HprofThreadData( namestr, id, addr, grpstr );
657 _threads_list.put( (int) addr, td );
658 } else {
659 System. out. println( "### Malformed thread ??: " + s );
660 }
661 }
662
663
664 public void handleThreadEnd( String s ) {
665 }
666
667
668 public int handleHeapDumpEnd( String s ) {
669
670 if ( MadmapMain.verbose() ) {
671 System. out. println( "Found the end: " + s );
672 }
673 return -1;
674 }
675
676
677 public void handleTrace( String s ) {
678 String traceid = matchAndGet( _stack_trace_title_re, s );;
679 String next = null;
680 String elem = null;
681 Vector backtrace = new Vector();
682 HprofStackTraceData sd = null;
683
684 if ( traceid == null ) {
685 System. out. println( "### Malformed trace title ??: " + s );
686 return;
687 }
688
689 next = readNextLine();
690 while ((next != null) && ( _stack_trace_item_re.match( next ))) {
691 elem = _stack_trace_item_re.getParen( 1);
692 elem = elem.intern();
693 backtrace.add( elem );
694 next = readNextLine();
695 }
696
697 if ( next != null) {
698 pushBack( next );
699 }
700
701
702 int id = Integer.parseInt( traceid, 10 );
703 sd = new HprofStackTraceData( id, backtrace );
704 getStackTraces().put( id, sd );
705 }
706
707
708 public void pushBack( String s ) {
709 _pushed_string = s;
710 }
711
712
713 public String readNextLine() {
714 try {
715 if ( _pushed_string != null ) {
716 String s = _pushed_string;
717 _pushed_string = null;
718 return s;
719 } else {
720 _linesSeen++;
721 if ( MadmapMain.verbose() && ((_linesSeen % 200000) == 0)) {
722 float rate = (float) _linesSeen / (float) elapsedTime();
723 System. out. println( elapsedTime() + ": Processed " + _linesSeen + " lines from " + _startOffset + ", " + rate + "/sec" );
724 }
725 if (( ! MadmapMain.noGUI()) && ( _readerId == 0 )) {
726 _owner.getWindow().getProgressBar().setValue((int)_linesSeen);
727 _owner.getWindow().updateMemoryProgressBar();
728 }
729
730 String ln = _bfr. readLine();
731
732
733 return ln;
734 }
735 } catch ( Exception ie ) {
736 System. out. println ( "readNextLine : Caught " + ie );
737 return null;
738 }
739 }
740
741
742 public void readAndProcessLines(int max) {
743 long linesRead = 0;
744 String theInput = null;
745 int result = 0;
746 try {
747 theInput = _bfr. readLine();
748 while((theInput != null) && (result == 0)) {
749 result = processLine( theInput );
750 theInput = readNextLine();
751 }
752 } catch (OutOfMemoryError e) {
753 JOptionPane.showMessageDialog(_owner.getWindow(),
754 "Sorry, cannot continue. Relaunch Madmap with larger heap size.",
755 "OutOfMemoryError", JOptionPane.ERROR_MESSAGE);
756 System.out.println("OutOfMemoryError in reader thread. ");
757 e.printStackTrace();
758 System.exit(-1);
759 } catch ( Throwable ie ) {
760 System. out. println ( "processLine : Caught " + ie + " near line " + _linesSeen + " : " + theInput );
761 ie.printStackTrace();
762 System.exit(-1);
763 }
764 }
765
766 public int processLine(String theInput) {
767
768
769
770
771
772 if( theInput.startsWith( objStart ) ) {
773
774 return handleObject( theInput );
775
776
777 } else if( theInput.startsWith( arrStart ) ) {
778
779 return handleArray( theInput );
780
781
782 } else if( theInput.startsWith( clsStart ) ) {
783
784 handleClass( theInput );
785
786 } else if( theInput.startsWith( "ROOT " ) ) {
787
788 handleRoot( theInput );
789 } else if( stack_trace_re. match( theInput ) == true ) {
790
791
792 handleTrace( theInput );
793 } else if( thread_start_re. match( theInput ) == true ) {
794
795 handleThreadStart( theInput );
796 } else if( thread_end_re. match( theInput ) == true ) {
797 handleThreadEnd( theInput );
798 } else if( _heap_dump_begin_re. match( theInput ) == true ) {
799 handleHeapDumpStart( theInput );
800 } else if( _heap_dump_end_re. match( theInput ) == true ) {
801 handleHeapDumpEnd( theInput );
802 } else {
803
804
805
806 }
807 return 0;
808 }
809
810
811 public float elapsedTime() {
812 return (float)(System.currentTimeMillis() - _startTime)/(float)1000.0;
813 }
814 }
815
816 }
817