在我们日常使用中,创建对象通常new一下就行了,当JVM遇到new指令时,会检查要new的这个对象的类是否已被加载、解析和初始化过。如果没有,那就要先执行相应的类加载过程,这里不讨论。
在类加载完成后,JVM会为这个新生的对象分配内存。对象所需内存的大小在类加载完成后便能确定。所以只需从堆里划分出一个确定大小的内存空间就行了。我们知道堆内存是GC的主要区域,GC靠的是垃圾收集器,
不同的垃圾收集器采用的垃圾收集算法不尽相同,GC完成后,内存存在两种情况:连续和不连续
可用内存
不可用内存
不连续内存
连续内存
如果内存是连续的,中间放一个指针作为分界指示器,给对象分配内存只需将指针向空闲的一边挪动一段与对象大小相等的距离即可,这种分配方式称为“指针碰撞”(Bump the Pointer)
如果内存是不连续的,那指针碰撞就不行了,JVM需要维护一个列表,记录上哪些内存是可用的,在分配的时候从列表里找到一块足够大的空间划分给对象实例,并更新列表的记录,这种分配方式称为“空闲列表”(Free List)
除了如何划分空间以外,还有一个问题需要考虑,那就是JVM上对象的创建是非常频繁的,在并发的情况下并不是线程安全的。解决这个问题有两种方案:
建立对象是为了使用对象,java程序需要通过栈上的reference数据来操作堆上的具体对象。由于reference类型在JVM规范中只规定了一个指向对象的引用,并没有定义这个引用通过何种方式去定位、访问堆中的对象的具体位置,
所以对象的访问方式也取决于jvm的具体实现。目前主流的访问方式有使用句柄和直接指针两种。HotSpot是使用直接指针来进行对象访问的。
原文:https://www.cnblogs.com/liuwhut/p/12628172.html