Package org.apache.kato.hprof.java

Source Code of org.apache.kato.hprof.java.JavaHeapImpl

/*******************************************************************************
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package org.apache.kato.hprof.java;

import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.NoSuchElementException;

import javax.tools.diagnostics.image.CorruptDataException;
import javax.tools.diagnostics.image.ImageAddressSpace;
import javax.tools.diagnostics.image.ImagePointer;
import javax.tools.diagnostics.runtime.java.JavaClass;
import javax.tools.diagnostics.runtime.java.JavaObject;

import org.apache.kato.common.BasicType;
import org.apache.kato.common.IteratorBackedList;
import org.apache.kato.common.ObjectMapList;
import org.apache.kato.hprof.HProfView;
import org.apache.kato.hprof.IJavaClass;
import org.apache.kato.hprof.IJavaClassLoader;
import org.apache.kato.hprof.datalayer.IGCInstanceHeapDumpRecord;
import org.apache.kato.hprof.datalayer.IGCObjectArrayHeapDumpRecord;
import org.apache.kato.hprof.datalayer.IGCPrimitiveArrayHeapDumpRecord;
import org.apache.kato.hprof.datalayer.IHProfRecord;
import org.apache.kato.hprof.datalayer.IHeapDumpHProfRecord;
import org.apache.kato.hprof.datalayer.IHeapObject;


/**
* Contains the contents of the heap - JavaClasses and JavaClassLoaders and object
* of all sorts.
*
*
*/
public class JavaHeapImpl implements IJavaHeapInternal {
  private HProfView view=null;
  long  heapRecordId=0;
  private ImageAddressSpace addressSpace;
 
  public JavaHeapImpl(HProfView view,long loc, ImageAddressSpace addressSpace) {
    if(loc<1) throw new IllegalArgumentException("heap record id ["+loc+"] is less than 1");
    this.view=view;
    this.heapRecordId=loc;
    this.addressSpace = addressSpace;
  }
 
  @Override
  public String getName() {
   
    return ""+heapRecordId;
  }

  List heapList = null;
  @Override
  public List getObjects() {
   
    final IHeapDumpHProfRecord record=view.getHeapRecord();
   
    if(record==null) return new LinkedList();
   
   
    if (heapList == null) {
   
    Iterator iter = new Iterator(){
     
      int latestRecord=0;
      private JavaObject nextObject=null;
     
      @Override
      public boolean hasNext() {
       
        if(nextObject!=null) return true;
       
        while(true) {
          IHProfRecord subRecord=record.getSubRecord(latestRecord);
          if(subRecord==null) {
            return false;
          }
         
          latestRecord++;
         
          // is this an object record?
          if(subRecord instanceof IGCInstanceHeapDumpRecord) {
            IGCInstanceHeapDumpRecord instance = (IGCInstanceHeapDumpRecord) subRecord;
           
            nextObject = new JavaObjectInstanceImpl(JavaHeapImpl.this, instance);
            return true;
          } else if (subRecord instanceof IGCObjectArrayHeapDumpRecord) {
            IGCObjectArrayHeapDumpRecord objArray = (IGCObjectArrayHeapDumpRecord) subRecord;
            nextObject = new JavaObjectArrayImpl(JavaHeapImpl.this, objArray);
            return true;           
          } else if (subRecord instanceof IGCPrimitiveArrayHeapDumpRecord) {
            IGCPrimitiveArrayHeapDumpRecord primArray = (IGCPrimitiveArrayHeapDumpRecord) subRecord;
            nextObject = new JavaPrimitiveArrayImpl(JavaHeapImpl.this, primArray);
            return true;
          }
       
         
        }

      }

      @Override
      public Object next() {
        if (hasNext()) {
          // We'll never get a new object if nextObject is never null...
          Object returnObject = nextObject;
          nextObject = null;
          return returnObject;
        } else {
          throw new NoSuchElementException("JavaHeap.getObjects() reached past end of iterator.");
        }
      }

      @Override
      public void remove() {
        throw new UnsupportedOperationException("JavaHeap.getObject() Iterator.remove() method not supported.");       
      }};
   
   

      iter.hasNext(); // initialize iterator.
      heapList = new IteratorBackedList(iter);
    }
    return heapList;
  }

 
  @Override
  public List getSections() {
    return new LinkedList();
  }

  /**
   * Retrieves an object by it's ID.
   *
   * @param ID
   * @return
   */
  @Override
  public JavaObject getObjectByID(Long ID) {
    if (ID.longValue() == 0L) {
      return null;
    }
   
   
    IHeapObject obj = view.getJavaObjectByID(ID);

    if(obj == null) {
      return null;
    }
   
    if (obj instanceof IGCInstanceHeapDumpRecord) {
      return new JavaObjectInstanceImpl(this, (IGCInstanceHeapDumpRecord)obj);
    } else if (obj instanceof IGCObjectArrayHeapDumpRecord) {
      return new JavaObjectArrayImpl(this, (IGCObjectArrayHeapDumpRecord) obj);
    } else if (obj instanceof IGCPrimitiveArrayHeapDumpRecord) {
      return new JavaPrimitiveArrayImpl(this, (IGCPrimitiveArrayHeapDumpRecord) obj);
    }
   
    return null;
  }

  private HashMap<Long,JavaClassImpl> classCache = new HashMap<Long,JavaClassImpl>();

  /**
   * Provides a single point for getting classes.
   * All class instantiations should go through here.
   *
   * @param ID ID of a class.
   * @return JavaClassImpl
   */
  public JavaClassImpl getJavaClassByID(long ID) {
    JavaClassImpl javaClass = classCache.get(ID);
   
    if (javaClass == null) {
      IJavaClass clazz = view.getJavaClassByID(ID);
      javaClass = new JavaClassImpl(this, clazz);
      classCache.put(ID, javaClass);
    }
   
    return javaClass;
  }

  final static private String primitiveArrayClassNames[] = {"[Z","[C","[F","[D","[B","[S","[I","[J"};
 
  private JavaClass[] primitiveArrayClasses = new JavaClass[8];
 
  /**
   * Gets the primitive array of the passed basic type.
   *
   * @see javax.tools.diagnostics.common.BasicType
   * @param type a value from 4 to 11
   * @return JavaClassImpl of a primitive array
   */
  public JavaClass getPrimitiveArrayClass(short type) {
    if (type <4 || type > 11) {
      throw new IllegalArgumentException("Passed invalid basic type id "+type);
    }
   
    JavaClass clazz = primitiveArrayClasses[type-4];
   
    if(clazz == null) {
      IJavaClass viewClass = view.getPrimitiveArrayClass(type);
     
      if (viewClass != null) {
        long ID = viewClass.getClassObjectID();
        clazz = getJavaClassByID(ID);
      } else {
        // create synthetic class.
        clazz = new JavaSyntheticPrimitiveArrayImpl(getPrimitiveClass(type), primitiveArrayClassNames[type-4],
            this.getJavaClassLoaderByID(0));
      }
      primitiveArrayClasses[type-4] = clazz;
    }
   
    return clazz;
  }
 
  private JavaPrimitiveClassImpl[] primitiveClasses = new JavaPrimitiveClassImpl[8];
  public JavaPrimitiveClassImpl getPrimitiveClass(int type) {
    if (type < 4 || type > 11) {
      throw new IllegalArgumentException("Passed invalid basic type id "+type);
    }
   
    JavaPrimitiveClassImpl clazz = primitiveClasses[type-4];
   
    if (clazz == null) {
      String name;
 
      switch(type) {
      case BasicType.BOOLEAN:
        name = "boolean";
        break;
      case BasicType.BYTE:
        name = "byte";
        break;
      case BasicType.SHORT:
        name = "short";
        break;
      case BasicType.CHAR:
        name = "char";
        break;
      case BasicType.INT:
        name = "int";
        break;
      case BasicType.LONG:
        name = "long";
        break;
      case BasicType.FLOAT:
        name = "float";
        break;
      case BasicType.DOUBLE:
        name = "double";
        break;
        default:
           name ="<invalid primitive class type "+type+">";
      }
     
      clazz = primitiveClasses[type-4] = new JavaPrimitiveClassImpl(name, getImagePointer(type),
          this.getJavaClassLoaderByID(0)); // The system class loader is 0
    }
   
    return clazz;
  }
 
  /**
   * Map from JavaClassLoader IDs to JavaClassLoaders.
   */
  private ObjectMapList<Long,JavaClassLoaderImpl> javaClassLoaders;

  /**
   * Create a map of JavaClassLoader object ID's to JavaClassLoaderImpl's.
   *
   * JavaClassLoaders are expected to be sufficiently low in number to warrant
   * keeping a definitive collection to avoid duplication by JavaClasses.
   */
  private void createJavaClassLoaders() {
    if (javaClassLoaders == null) {
      javaClassLoaders = new ObjectMapList<Long,JavaClassLoaderImpl>();
      for (IJavaClassLoader loader : view.getJavaClassLoaders()) {
        javaClassLoaders.put(loader.getID(),new JavaClassLoaderImpl(this, loader));
      }
     
      // We also want to get the Classloaders that have no class instances.
      Iterator objects = getObjects().iterator();
      while (objects.hasNext()) {
        Object next = objects.next();
       
        if (next instanceof JavaObjectInstanceImpl) {
          try {
            JavaClass clazz = ((JavaObject) next).getJavaClass();
           
            while(clazz != null) {
              if ("java/lang/ClassLoader".equals(clazz.getName()) ) {
                JavaObjectInstanceImpl obj = (JavaObjectInstanceImpl) next;
                long id = obj.getObjectID();
               
                if (javaClassLoaders.get(id) == null) {
                  javaClassLoaders.put(id, new JavaClassLoaderImpl(this, new EmptyClassLoaderImpl(id)));
                }
              }
             
              clazz = clazz.getSuperclass();
            }
          } catch (CorruptDataException e) {
            e.printStackTrace();
          }
         
        }
      }
    }
  }
 
  @Override
  /**
   * Returns the java class loaders
   * @return
   */
  public List<JavaClassLoaderImpl> getJavaClassLoaders() {
    createJavaClassLoaders();
    return javaClassLoaders.values();
  }
  /**
   * Retrieve a JavaClassLoaderImpl by it's ID.
   * Used by JavaClassImpl.
   * 
   * @param ID
   * @return
   */
  @Override
  public JavaClassLoaderImpl getJavaClassLoaderByID(long ID) {
    createJavaClassLoaders();
    return javaClassLoaders.get(ID);
  }

  @Override
  public String getUTF8StringByID(long ID) {
    return view.getUTF8String(ID);
  }

  @Override
  public ImagePointer getImagePointer(long address) {
    return addressSpace.getPointer(address);
  }
 
}
TOP

Related Classes of org.apache.kato.hprof.java.JavaHeapImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.