Processing/Graph Analysis

Back to Contents
  • Processing
  • Setting Process Options
  • Processing from (and Reachability of) a Specific Object
  • Keep-Alive of an Object

  • Processing

    When you first load a heapdump, it is unprocessed. Processing (see algorithms) involves analysing the object graph and storing data connecting the 'root's of the graph and the other objects. This includes the descendants number and total/subtree size of each object, plus classifying each object as either a non-root (N), an artificial root (A) or a pure root (R).

    Processing can be performed by running the 'p' command.

    Memory Usage       : 41/88 mb      Memory usage before process.  
    
    Enter: o{a,s,t,d,m,n}, g{c,s}, t{c,s,n}, i, p, d{t,d,m} or help for more info
    > p
    
    Requesting at least 25 mb of heapspace to process heapdump
    Finding pure Roots
    ...................................................................... done.
    DFS from pure Roots
    ................................................................       done.
    DFS from objects unreached from Roots (5,385)
                                                                           done.
    Comments           :
    Dump has flags     : false
    # Objects          : 2,045,571
    # Refs             : 2,635,243
    # Unresolved refs  : 98
    Heap usage         : 129,581,536
    Total Object Range : 188,203,216
    
    Pure roots         : 39,082        Objects without any parents,
    ... which reach    : 2,040,186     these reach most of the heap.
    Artificial roots   : 373           373 'extra' roots are required to reach the remainder.
    Softlinks followed : 14            14 Weak,Phantom or Soft references were followed.
    
    Memory Usage       : 68/88 mb      Now using more memory.
    
    

    Now many of the commands now have more information available. The commands in the sections below offer some further investigation techniques.

    Top


    Setting Process Options

    Note these options will apply to the next run of 'k' or 'p', not the current data.

    Run '? p':

        Follow soft,weak & phantom references ? [Y]

    Enter 'N' to ignore these types of references. See soft-links

        Select data to store (more data increaes memory usage) [T]
        total/subtree sizes(T), # descendants(D), maximum depth(M)
    

    Select the data to be made available (here the default of only total-size (T) is selected). 'TDM' would select all 3 items of data. Note, selecting more uses more memory. See the definitions for descriptions of 'total-size', 'descendants' etc.

    For example, if you selected 'DM' you would have the option (after processing again with 'p') of sorting by descendants or max-depth with 'od' or 'om' in the objects table but the total-size values would no longer be available.

    Top


    Processing from (and Reachability of) a Specific Object

    The 'p' command as above starts from the pure-root with the lowest address and assigns all objects reachable to it. It then continues with the next root until all objects have been assigned/owned. This is described in Definitions & Algorithms.

    If you want more information on specific object(s) then you can run:

          p 0x1234      process from object 0x1234. This can be any object
                        and clears any previous 'p {0xaddr}' data.
    

    The effect of this is that everything reachable from 0x1234 will then have its root-owner set to 0x1234. It is quite likely that 0x1234 will now have a larger total-size than before because it owns as many objects as it can possibly reach and all these objects count towards its size.

    For an example dump, I have chosen a Vector to process from (it is in-fact a root) at address 0x033b2420. Before doing this, I turned 'Descendants' on with '? p', ran 'p' and the output of 'i 0x033b2420' gave:

         Total size        : 51,330,568
         Descendants       : 95,871
         Max Depth         : 3
    

    Now running:

    > p 0x033b2420
    
    Processing from 0x033b2420 'java/util/Vector' ...
    .....more status.....
    DFS from 0x033b2420
    Reached 100,499 objects. Total-size is 51,591,456.   Some more objects are now
                                                         owned by 0x033b2420.
    

    We can see from above that 0x033b2420 can reach 100,499 objects (this includes itself) and 'i 0x033b2420' now gives:

         Total size        : 51,591,456    
         Descendants       : 100,498       This doesn't include itself
         Max Depth         : 50
    

    This shows that this root now owns more objects and has a deeper tree depth.

    Other example queries are:

    What types of objects are reachable from any object 0x5678 ?
    Run 'p 0x5678' and then use the 't' command selecting 0x5678 are the root-owner to filter on. This will give you a breakdown of all the objects reachable from 0x5678 in terms of their type, showing total heap usage and instance count of each type. You can find out more information by using 'o' and specifying the root-owner to be 0x5678 also.
    Can 0x1234 reach 0x5678 ?
    Run 'p 0x1234' and then use the 'i 0x5678' command to find the root-owner of 0x5678. If it is 0x1234 then it has been reached by 0x1234.
    Is 0x1234's reachability affected by the Soft references ?
    You may see that some weak/soft/phantom references have been followed, say after running 'p 0x1234' shown by : Softlinks followed : 3.

    You can stop soft-links from being followed by using the settings command then repeat 'p 0x1234'. If you see differences in the reachability number then you know that not everything reached from 0x1234 is strongly reachable. You could then look at instances of reference classes e.g. start by looking at types whose name contains 'java/lang/ref'.

    Top

    Keep-Alive of an Object

    The command 'k 0x1234' will calculate the keep-alive size of 0x1234.

    This executes by first running 'p 0x1234'. This leaves every object reachable by 0x1234 owned by it. Then any objects which are owned by 0x1234 but reachable from outside of this set are removed. This leaves 0x1234 owning exactly those objects which are only reachable thru' it.

    In my Vector example above, I run:

    > k 0x033b2420
    
    Calculating keep-alive size of 0x033b2420 'java/util/Vector' ...
    .... status .....
    Total reach (inclusive) 100,499 objects. Total-size is 51,591,456.
    .... status .....
    Found 4,627 objects which are reachable from elsewhere.
    These will be taken from 0x033b2420 and then owned by other objects ...
    .... status .....
    Keep-alive size (inclusive) is 95,872 objects. Total-size is 51,330,568.
    

    Can now see that this Vector references about 100k objects (it is an array of objects, which themselves reference other objects) but only 5k of these objects would exist should the Vector become garbage collected. It is in a sense 'Keeping alive' 95k objects.

    Top