对象的创建过程有如下步骤:
1.类加载检查:
????????虚拟机遇到一个new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载、解析和初始化过,如果没有,那么必须先执行相应的类加载过程
????????new指令对应到语言层面上讲是,new关键词、对象克隆、对象序列化等。
2.分配内存
????????对象所需内存的大小在类加载完成后便可完全确定,为对象分配空间的任务等同于把一块确定大小的内存从Java堆中划分出来。这个步骤有两个问题:
3.初始化
????????内存分配完成后,虚拟机需要将分配到的内存空间都初始化为零值(不包括对象头),如果使用TLAB,这一工作过程也可以提前至TLAB分配时进行。这一步操作保证了对象的实例字段在Java代码中可以不赋初始值就直接使用,程序能访问到这些字段的数据类型所对应的零值。
4.设置对象头
????????对象除了成员变量之外,还有对象头,对象填充,对象在内存中存储的布局可以分为3块区域:对象头、实例数据和对齐填充
????????1.Mark Word标记字段(32位占4字节,64位占8字节)自身运行时数据哈希表,GC分代年龄,锁状态标志,线程执有锁,偏向线程ID,偏向时间戳。
????????2.Klass Pointer类型指针(开启压缩4字节,关闭压缩8字节)。剋的元数据指针(D。代码放在方法区,JVM使用Java头的类型指针拿到方法区的头。
????????3.数组长度(4字节,只有数组对象才有)
5.执行(init)方法
????????给对象真正的赋值以及执行构造方法。
对象大小与指针压缩
????????启用指针压缩-XX:+UseCompressedOops(默认开启),禁止-XX:-UseCompressedOops
压缩对象地址到32位
为什么要进行指针压缩?
????????-XX:+UseCompressedClassPointers默认开启的,只压缩对象头里的类型指针Klass Pointer对象内存分配。
????????对象逃逸分析:比如User对象在方法执行后返回,则这个对象逃逸了,减少GC压力。
????????-XX:DoEscopeAnalysis开启逃逸分析参数,JDK7后默认开启
????????标量替换:一个对象如果经过逃逸分析能够确定这个对象在栈上分配,这里会做一个优化,即便栈帧里没有一整块空间放对象,也能够通过其他方法存在栈帧上。
????????如果对象不逃逸,栈帧只放对象成员变量,把完整的对象打散放到栈帧上去,这几个变量都标识属于某一个对象。
????????标量与聚合量:标量即不可以被进一步分解的量,而Java的基本数据类型就是标量,标量的对立就是可以被进一步分解的量,而这种量称为聚合量。而Java对象就是可以被进一步分解的聚合量。
????????开启标量替换-XX:+ECiminateAllocations,JDK7后默认开启
????????-Xmx 15m -Xms 15m -XX:+DoEscapeAnslysis -XX:+printGC -XX:+ElininoteAllocations.大对象直接进入老年代
????????-XX:PretenurefSizeThreshold=1000000 -XX:+UseSerialGC(支持大对象ParNew)。定义大对象配置,这个参数只在Serial和ParNew两个收集器下有效
????????长期存活的对象将进入老年代。当它的年龄增加到一定程度,默认为15岁,CMS收集器默认为6岁,通过-XX:maxTennringThreshold设置对象动态年龄判断。
对象动态年龄判断:
????????如果S区超过50%,进入老年代,例如Survivor区域里现在有一批对象年龄1+年龄2+年龄n的多个年龄对象总和超过了Survivor区域的50%,此时会把年龄n(含)以上的对象都放入老年代,这个规则其实是希望那些可能是长期存活的对象,尽早进入老年代,对象动态年龄判断机制一般是在minor gc之后触发。把年轻代设大点(-Xmn)
老年代空间分配担保机制
软引用、弱引用和虚引用在GC时没空间时会被回收。
finalize()方法最终判定对象是否存活。
如果你的对象实现了finalize,这个对象会做标记,不会马上回收,第二次标记,清理掉前执行该方法,finalize只会自救一次。
如何判断一个类是无用的类,方法区主要回收的是无用的类,那么如何判断一个类时无用类呢?
类在方法区,该区要被回收满足该类的实例都被回收。
????????加载类的Class Loader被回收了,自定义的类加载器是有可能需要回收,比如JSP类加载器。
该类对应的java.lang.Class对象没有任何地方被引用,无法在任何地方通过反射访问该类的方法。