JVM MEMORY(虚拟机内存模型)+计算对象占用内存程序

在这里插入图片描述
在这里插入图片描述
函数的基本类型存储
在这里插入图片描述
函数的引用类型存储
在这里插入图片描述

分析String所占用的字节:
jdk1.8String的对象成员:

    /** The value is used for character storage. */
    private final char value[];

    /** Cache the hash code for the string */
    private int hash; // Default to 0

    /** use serialVersionUID from JDK 1.0.2 for interoperability */
    private static final long serialVersionUID = -6849794470754667710L;

首先String是一个类在这里插入图片描述
在这里插入图片描述

我们String a=new String(“aaa”);就会在堆中开辟内存
String a=“aaa”;会在方法区的常量池里开辟内存。

String a=new String(“aaa”);
UseCompressedOops默认是开启的>>>>>>>>>

在网上找了一个包,可以查看虚拟机状态,以及对象信息。
它给出的答案明显是48(一般内存的使用都是8字节的倍数,不够八字节自动填充为8字节倍数)
在这里插入图片描述
对象自己开销24字节:
12对象头+4存char数组指针+4存int类型的hash+4字节填充=24
实例化开销24字节:(其实就是实例化出来一个char数组)
数组是一个对象12个字节的对象头+4字节的数组长度存取+一个字符占用2字节*3个‘a’=22+2(字节自动补齐)
做一个小例子吧

public class Person {
    private  int a;
}

 Person p=new Person();

此时系统为这个新对象开辟多少内存

我自己理解:
8字节对象头+4字节引用指针(p)+4字节变量a的开销=16
和我的期望是一样的12字节的对象头+4字节a变量的所占内存
在这里插入图片描述
计算对象占用内存的程序(从别人的CSDN看到的,也是从github上弄下来的,一个国外大佬写的)
需要去仓库下载一个包:
在这里插入图片描述

import org.openjdk.jol.vm.VirtualMachine;
import org.openjdk.jol.vm.VM;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.*;
import java.lang.*;
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();
    }
}

扩展(不用国外大佬程序 我们去看对象信息依然能计算出来对象内存)

        // 查看虚拟机信息
        System.out.println(VM.current().details());
        // 查看对象信息
        System.out.println(ClassLayout.parseInstance(p).toPrintable());

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值