2024年1月21日发(作者:)
public final int arraySize;/** This object fields */public final List children;public ObjectInfo(String name, String type, String contents, int offset, int length, int arraySize,int arrayBase, int arrayElementSize){ = name; = type;ts = contents; = offset; = length;ize = arraySize;ase = arrayBase;lementSize = arrayElementSize;children = new ArrayList( 1 );}public void addChild( final ObjectInfo info ){if ( info != null )( info );}/*** Get the full amount of memory occupied by a given object. This value may be slightly less than* an actual value because we don't worry about memory alignment - possible padding after the last object field.** The result is equal to the last field offset + last field length + all array sizes + all child objects deep sizes* @return Deep object size*/public long getDeepSize(){//return length + arraySize + getUnderlyingSize( arraySize != 0 );return addPaddingSize(arraySize + getUnderlyingSize( arraySize != 0 ));}long size = 0;
private long getUnderlyingSize( final boolean isArray ){//long size = 0;for ( final ObjectInfo child : children )size += ize + erlyingSize( ize != 0 );if ( !isArray && !y() ){int tempSize = ( () - 1 ).offset + ( () - 1 ).length;size += addPaddingSize(tempSize);}return size;}private static final class OffsetComparator implements Comparator{@Overridepublic int compare( final ObjectInfo o1, final ObjectInfo o2 ){return - ; //safe because offsets are small non-negative numbers}}//sort all children by their offsetpublic void sort(){( children, new OffsetComparator() );}@Overridepublic String toString() {final StringBuilder sb = new StringBuilder();toStringHelper( sb, 0 );return ng();}private void toStringHelper( final StringBuilder sb, final int depth ){depth( sb, depth ).append("name=").append( name ).append(", type=").append( type ).append( ", contents=").append( contents ).append(", offset=").append( offset )
.append(", length=").append( length );if ( arraySize > 0 ){(", arrayBase=").append( arrayBase );(", arrayElemSize=").append( arrayElementSize );( ", arraySize=").append( arraySize );}for ( final ObjectInfo child : children ){( 'n' );ngHelper(sb, depth + 1);}}private StringBuilder depth( final StringBuilder sb, final int depth ){for ( int i = 0; i
( "t");return sb;}private long addPaddingSize(long size){if(size % 8 != 0){return (size / 8 + 1) * 8;}return size;}}package test;import ;import ;import er;import ist;import ;import tions;import p;
import tyHashMap;import ;import ;import ;/*** This class could be used for any object contents/memory layout printing.*/public class ClassIntrospector {private static final Unsafe unsafe;/** Size of any Object reference */private static final int objectRefSize;static {try {Field field = laredField("theUnsafe");essible(true);unsafe = (Unsafe) (null);objectRefSize = ndexScale(Object[].class);} catch (Exception e) {throw new RuntimeException(e);}}/** Sizes of all primitive values */private static final Map primitiveSizes;static {primitiveSizes = new HashMap(10);(, 1);(, 2);(, 4);(, 8);(, 4);(, 8);(, 1);}/**
* Get object information for any Java object. Do not pass primitives to* this method because they will boxed and the information you will get will* be related to a boxed version of your value.** @param obj* Object to introspect* @return Object info* @throws IllegalAccessException*/public ObjectInfo introspect(final Object obj)throws IllegalAccessException {try {return introspect(obj, null);} finally { // clean visited cache before returning in order to make// this object reusablem_();}}// we need to keep track of already visited objects in order to support// cycles in the object graphsprivate IdentityHashMap m_visited = new IdentityHashMap(100);private ObjectInfo introspect(final Object obj, final Field fld)throws IllegalAccessException {// use Field type only if the field contains null. In this case we will// at least know what's expected to be// stored in this field. Otherwise, if a field has interface type, we// won't see what's really stored in it.// Besides, we should be careful about primitives, because they are// passed as boxed values in this method// (first arg is object) - for them we should still rely on the field// n isPrimitive = fld != null && e().isPrimitive();boolean isRecursive = false; // will be set to true if we have already
// seen this objectif (!isPrimitive) {if (m_nsKey(obj))isRecursive = true;m_(obj, true);}final Class type = (fld == null || (obj != null && !isPrimitive)) ? ss() : e();int arraySize = 0;int baseOffset = 0;int indexScale = 0;if (y() && obj != null) {baseOffset = aseOffset(type);indexScale = ndexScale(type);arraySize = baseOffset + indexScale * gth(obj);}final ObjectInfo root;if (fld == null) {root = new ObjectInfo("", onicalName(), getContents(obj,type), 0, getShallowSize(type), arraySize, baseOffset,indexScale);} else {final int offset = (int) FieldOffset(fld);root = new ObjectInfo(e(), onicalName(),getContents(obj, type), offset, getShallowSize(type),arraySize, baseOffset, indexScale);}if (!isRecursive && obj != null) {if (isObjectArray(type)) {// introspect object arraysfinal Object[] ar = (Object[]) obj;for (final Object item : ar)if (item != null)ld(introspect(item, null));
} else {for (final Field field : getAllFields(type)) {if ((ifiers() & ) != 0) {continue;}essible(true);ld(introspect((obj), field));}}}(); // sort by offsetreturn root;}// get all fields for this class, including all superclasses fieldsprivate static List getAllFields(final Class type) {if (itive())return ist();Class cur = type;final List res = new ArrayList(10);while (true) {(res, laredFields());if (cur == )break;cur = erclass();}return res;}// check if it is an array of objects. I suspect there must be a more// API-friendly way to make this e static boolean isObjectArray(final Class type) {if (!y())return false;if (type == byte[].class || type == boolean[].class|| type == char[].class || type == short[].class
|| type == int[].class || type == long[].class|| type == float[].class || type == double[].class)return false;return true;}// advanced toString logicprivate static String getContents(final Object val, final Class type) {if (val == null)return "null";if (y()) {if (type == byte[].class)return ng((byte[]) val);else if (type == boolean[].class)return ng((boolean[]) val);else if (type == char[].class)return ng((char[]) val);else if (type == short[].class)return ng((short[]) val);else if (type == int[].class)return ng((int[]) val);else if (type == long[].class)return ng((long[]) val);else if (type == float[].class)return ng((float[]) val);else if (type == double[].class)return ng((double[]) val);elsereturn ng((Object[]) val);}return ng();}// obtain a shallow size of a field of given class (primitive or object// reference size)private static int getShallowSize(final Class type) {


发布评论