Java中获取对象内存使用大小

对于对象创建后内存使用情况,看了很多大佬的博客,由于自己对大佬写的流程(获取JAVA对象内存大小的方法)不太理解,经过多次的实验和尝试,最后我在gitHub找到了类似上面的那个方法,下面直接贴上链接(这个是国外友人写的)和原码


import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Set;

import org.openjdk.jol.vm.VM;
import org.openjdk.jol.vm.VirtualMachine;

/**
 * Calculates the object size (deep/retained) by walking through the object
 * graph with JOL.
 *
 * @author F. Mannhardt
 * @author Aleksey Shipilev
 */
public class ObjectSize {

	private final VirtualMachine vm;

	private final Set<Object> visited;
	private final Object[] roots;

	public ObjectSize(Object... roots) {
		this.roots = roots;
		this.visited = Collections.newSetFromMap(new IdentityHashMap<Object, Boolean>());
		this.vm = VM.current();
	}

	public long calculateSize() {
		long size = 0;
		List<Object> curLayer = new ArrayList<Object>();
		List<Object> newLayer = new ArrayList<Object>();

		for (Object root : roots) {
			visited.add(root);
			size += size(root);
			curLayer.add(root);
		}

		while (!curLayer.isEmpty()) {
			newLayer.clear();
			for (Object next : curLayer) {
				for (Object ref : peelReferences(next)) {
					if (visited.add(ref)) {
						size += size(ref);
						newLayer.add(ref);
					}
				}
			}
			curLayer.clear();
			curLayer.addAll(newLayer);
		}

		return size;
	}

	private long size(Object obj) {
		return obj != null ? vm.sizeOf(obj) : 0;
	}

	private static List<Object> peelReferences(Object o) {

		if (o == null) {
			// Nothing to do here
			return Collections.emptyList();
		}

		if (o.getClass().isArray() && o.getClass().getComponentType().isPrimitive()) {
			// Nothing to do here
			return Collections.emptyList();
		}

		List<Object> result = new ArrayList<Object>();

		if (o.getClass().isArray()) {
			for (Object e : (Object[]) o) {
				if (e != null) {
					result.add(e);
				}
			}
		} else {
			for (Field f : getAllReferences(o.getClass())) {
				try {
					f.setAccessible(true);
				} catch (Exception e) {
					// Access denied
					result.add(null);
					continue;
				}

				try {
					Object e = f.get(o);
					if (e != null) {
						result.add(e);
					}
				} catch (IllegalAccessException e) {
					throw new IllegalStateException(e);
				}
			}
		}

		return result;
	}

	private static Collection<Field> getAllReferences(Class<?> klass) {
		List<Field> results = new ArrayList<Field>();

		for (Field f : klass.getDeclaredFields()) {
			if (Modifier.isStatic(f.getModifiers()))
				continue;
			if (f.getType().isPrimitive())
				continue;
			results.add(f);
		}

		Class<?> superKlass = klass;
		while ((superKlass = superKlass.getSuperclass()) != null) {
			for (Field f : superKlass.getDeclaredFields()) {
				if (Modifier.isStatic(f.getModifiers()))
					continue;
				if (f.getType().isPrimitive())
					continue;
				results.add(f);
			}
		}

		return results;
	}

	public static long sizeOf(Object obj) {
		return new ObjectSize(obj).calculateSize();
	}

仅供参考,如果大佬有其他的方法获得,请在下方回复下你的博客或者参考资料,谢谢

猜你喜欢

转载自blog.csdn.net/zy1367948142/article/details/86307397