/* * Copyright (C) 2016 The Android Open Source Project * * 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 com.android.ahat.heapdump; import java.util.AbstractList; import java.util.Arrays; import java.util.List; /** * A class from a parsed heap dump. * In addition to those methods inherited from {@link AhatInstance}, the class * provides methods for accessing information about the class object, such as * the class loader, superclass, static field values and instance field * descriptors. */ public class AhatClassObj extends AhatInstance { private String mClassName; private AhatClassObj mSuperClassObj; private AhatInstance mClassLoader; private FieldValue[] mStaticFieldValues; private Field[] mInstanceFields; private long mStaticFieldsSize; private long mInstanceSize; AhatClassObj(long id, String className) { super(id); mClassName = className; } void initialize(AhatClassObj superClass, long instanceSize, Field[] instanceFields, long staticFieldsSize) { mSuperClassObj = superClass; mInstanceSize = instanceSize; mInstanceFields = instanceFields; mStaticFieldsSize = staticFieldsSize; } void initialize(AhatInstance classLoader, FieldValue[] staticFields) { mClassLoader = classLoader; mStaticFieldValues = staticFields; } @Override long getExtraJavaSize() { return mStaticFieldsSize; } /** * Returns the name of the class this is a class object for. * For example, "java.lang.String". * * @return the name of the class */ public String getName() { return mClassName; } /** * Returns the superclass of this class object. * * @return the superclass object */ public AhatClassObj getSuperClassObj() { return mSuperClassObj; } /** * Returns the class loader of this class object. * * @return the class loader object */ public AhatInstance getClassLoader() { return mClassLoader; } /** * Returns the size of instances of this object. * The size returned is as reported in the heap dump. * * @return the class instance size */ public long getInstanceSize() { return mInstanceSize; } /** * Returns the static field values for this class object. * * @return the static field values */ public List getStaticFieldValues() { return Arrays.asList(mStaticFieldValues); } /** * Returns the fields of instances of this class. * Does not include fields from the super class of this class. * * @return the instance fields */ public Field[] getInstanceFields() { return mInstanceFields; } @Override Iterable getReferences() { List refs = new AbstractList() { @Override public int size() { return mStaticFieldValues.length; } @Override public Reference get(int index) { FieldValue field = mStaticFieldValues[index]; Value value = field.value; if (value != null && value.isAhatInstance()) { return new Reference(AhatClassObj.this, "." + field.name, value.asAhatInstance(), Reachability.STRONG); } return null; } }; return new SkipNullsIterator(refs); } @Override public boolean isClassObj() { return true; } @Override public AhatClassObj asClassObj() { return this; } @Override public String toString() { return "class " + mClassName; } @Override AhatInstance newPlaceHolderInstance() { return new AhatPlaceHolderClassObj(this); } }