java文件启动的一套流程:
.java---通过编译器javac---->.class---经过解释器&JIT--->机器码--->电脑可识别运行
一般而言,不是开发的安个jre就行,但类似于jsp编译就需要jdk的开发工具。
JIT(just in time)即使编译器,可对热点代码直接编译。所以说比解释性语言快些、解释和编译型语言
jdk9 出现AOT(ahead of time)预先编译,但不能全部都先编译,这是因为cglib的asm技术没有字节码做代理也就废了。
创建对象的流程:
1.检查累的加载过程,没加载的加载
2.内存分配:分配内存根据内存的规整,选择使用规整的指针碰撞,还是不规整的空闲队列,而是不是规整由垃圾回收器决定。
当然,内存分配也不是一方风顺,它会经历tlab,先分配内存,如果不足就使用cas+重试
3.初始化零值
4.设置对象头:包含类元信息、运行时的数据(锁状态、哈希值、GC年龄)
5.init: 对JVM是结束,对程序而言才开始
jdk8:
本地内存:元空间(运行时产量池(里面有各种引用))
运行时数据区:堆(jdk7移来的字符串常量池),栈,本地方法栈,程序计数器
堆中是GC主要地方,存放大量对象数据。
栈格式:局部变量表、操作数栈、动态链接、方法出口等
本地方法栈:主要是JNI调用时使用
程序计数器:唯一一个不会出现OOM的地方,1.记录程序执行位置,2.多线程转换上下文定位
GC算法:
标记-清除算法:标记出活跃对象,将不活跃的对象清除。执行效率低,存在大量内存碎片。
标记-复制算法:主要是分两块内存,将活跃对象转移另一个空间内存,在统一清除。当活跃对象多的时候不使用,内存缩水一半
标记-整理:同一块内存空间,将活跃对象已到内存另一段,移完后,在这段之外的内存同一清除。
分代收集算法:青年代复制算法、老年代标记-清除或整理算法
GC收集器(可以视作GC算法实现)
1.serial:青年代单线程标记-复制算法
2.ParNew:青年代多线程标记-复制算法
3.Parallel Scavenge:青年代多线程标记-复制算法,关注cpu\吞吐量,
4.seral old:兼容1.5之前版本搭配Parallel Scavenge,及cms的后备版本,老年代单线程标记--整理
5.parallel old:老年代多线程标记--整理
6.CMS: 并发处理,旨在降低停顿时间,初始标记-->并发标记->重标记 --->并发标记-清除
7.G1:面向服务器垃圾及回收,支持在多cpu并发,高吞吐量,底停顿,大内存
初始标记--》并发标记--〉终止标记--》筛选
8.ZGA:复制算法,牺牲一些吞吐量,停顿时间10MS, 不随堆的大小与对象的大小改变、堆大小支持8M-4T
快速原因:1.并发的运用,2.使用着色与读屏障,方便对对象的定位
注意:
对象内部分布=对象头+数据+对其填充(确保8字节)
对于方法区的访问是直接访问。
对象不一定都是在堆中,可能有栈的,这个查下分配、标量替换优化。
JDK 默认垃圾收集器(使用 java -XX:+PrintCommandLineFlags -version
命令查看):
- JDK 8:Parallel Scavenge(新生代)+ Parallel Old(老年代)
- JDK 9 ~ JDK20: G1
ZGA在11中试用、15成熟
标签:java,标记,--,基础,一小,对象,算法,GC,内存 From: https://www.cnblogs.com/Phneas/p/18124319