Java 学习(四)JVM对象的创建与内存分配

1、JVM对象创建
对象创建的基本流程:
Java 学习(四)JVM对象的创建与内存分配类加载检查:类在执行new指令(new对象、克隆、序列化)时,检查这个指令在常量池中找到类对应的符号引用,并检查这个类是否被加载/解析、初始化过,没有则进行类的加载过程;
分配内存:为对象在内存中分配一块内存区域,在类加载完之后就可以确定类的大++++小,为对象分配空间的任务等同于把 一块确定大小的内存从Java堆中划分出来。
初始化:内存分配完成之后,虚拟机需要将分配的内存空间初始化为零值;这一操作保证了对象的实例字段在java代码中,不赋初始值就可以直接使用;
设置对象头:对象在内存中主要包括:对象头、实例数据、补齐填充;对象头包括:对象自身的运行时数据;哈希码、GC标记、锁标记等;还有就是类元数据的指针:虚拟机可以通过类元数据指针标记该对象属于哪个类的实例;
执行方法:给对象赋值并执行构造方法;

2、对象内存分配:
指针碰撞:
Java内存中的空闲位置是比较规整的,即使用过的和未使用的分两边,中间放一个指针作为分界指示器;分配内存时就,指针向空闲位置移动指定大小位置;
空闲列表:
Java内存空闲位置不规整,虚拟机必须维护一个列表来标记空闲内存位置,分配的时候找到一块足够大的空间分配给对象,并更新列表;

内存分配并发问题的处理:
CAS(compare and swap):虚拟机采用CAS配上失败重试的方式保证更新操作的原子性来对分配内存空间的动作进行同步处理。
TLAB(Thread Local Allocation Buffer)本地线程分配缓存:把内存分配的动作按照线程划分在不同的空间之中进行,即每个线程在Java堆中预先分配一小块内存。通过­XX:+/­UseTLAB参数来设定虚拟机是否使用TLAB(JVM会默认开启­XX:+UseTLAB),­XX:TLABSize 指定TLAB大小

指针压缩是什么???
(1)jdk1.6版本64位操作系统支持指针压缩;
(2)启用指针压缩:­XX:+UseCompressedOops(默认开启),禁止指针压缩:­XX:­UseCompressedOops
为什么进行指针压缩??
(1)由于系统在执行对象复制,移动的时候会占用较大带宽而影响性能;同时GC也会承受较大压力;
(2)为了减少64位平台下内存的消耗,启用指针压缩功能
(3)堆内存小于4G时,不需要启用指针压缩,jvm会直接去除高32位地址,即使用低虚拟地址空间
(4)堆内存大于32G时,压缩指针会失效,会强制使用64位(即8字节)来对java对象寻址,这就会出现1的问题,所以堆内存不要大于32G为好

3、对象分配

Java 学习(四)JVM对象的创建与内存分配
4、对象内存回收

引用计数法:给对象中添加一个引用计数器,每当有一个地方引用它,计数器就加1;当引用失效,计数器就减1;任何时候计数器为0 的对象就是不可能再被使用的

可达性分析算法:将“GC Roots” 对象作为起点,从这些节点开始向下搜索引用的对象,找到的对象都标记为非垃圾对象,其余未标记的对象都是垃圾对象

GC Roots根节点:线程栈的本地变量、静态变量、本地方法栈的变量等等

5、判断一类是否无用??
(1)该类所对应的实例已全部回收;
(2)类对应的加载器也已回收;
(3)该类对应的类对象没有被引用;即无法在任何地方通过反射访问该类的方法