[TOC]
java虚拟机
以太坊,区块链1.0版本 比特币是1.0 以太坊2.0 -EVM
jvm就是对字节码的翻译
虚拟机的发展 go语言写jvm非常的简单
hotSpot VM
目前最广的java虚拟机JRockit VM
号称最快的java虚拟机J9 VM ibm公司的
Dalvik VM
未来java技术
模块化, GFGI 模块化,微服务
混合语言(java,Scala)
多核并行(函数式编程)
丰富语法
64位
更强的垃圾回收 回收gb级的 jdk11可以是tb级别
所有的东西都是放内存的 内存的划分,
程序计数器:指向当前线程的字节码,线程间切换来切换去
FILO first in last out
非常符合java间的方法调用
虚拟机栈 -Xss 里面有栈帧
javap
局部变量表,只能放32位的数据,局部变量表, this,money
持有引用,
操作数栈 ,
出栈进行相减
count++, dup - idd 总共4不
操作的入栈,
返回地址return,正常执行
异常会在一个叫 异常处理器表 处理
多态的的话,就要使用动态连接, java动态运行性,
局部变量表一个引用
native栈 hotspot吧本地方法栈和虚拟机栈合二为一的
加了入参,可能有点影响
为什么jvm要用栈,因为:非常符合java间的方法调用
指令 + 数据,
虚拟机栈帧,默认是1m, 可以进行修改
方法区: 类信息,常量,静态变量,即时编译器编译后的代码
java堆: 对象的实例(几乎所有) 数组
-xmx 最大
-xms 最小
直接内存: nio会使用
不超过,内存调用
每个线程归属于单个线程,栈
堆内存是对所有线程可见的
空间大小:并发可以跑一个100个线程,就100m
java虚拟机中的对象
分配内存
指针碰撞 和 空闲列表
规整用指针碰撞,不规整用空闲列表如果相同地址时:要使用cas锁
cas锁:比较和交换 乐观锁
cas操作带来的ABA
ABA 问题 中间状态,被用了,不管, 只要管再次分配的时候 b这个状态不管
char的初始值 \u0000 ???
对象初始化、
设置是那些类的, 然后对象初始化
对象内存的布局
对齐填充
对象头:线程 垃圾回收也有点关系。。。
对象的访问定位
句柄方式访问对象
直接指针访问对象
虚拟机优化技术 — 逃逸分析
有对象可以在栈上分配的,几乎所有对象在栈上分配
hotSpot 默认有逃逸分析
本地线程缓冲区
如果有逃逸分析,对象可能会在栈上分配,这是虚拟机的优化的技术
本身这个对象,没有在其他地方使用,所以就直接在栈上分配了
逃逸分析使用了可见性???,其他的线程也是可见的
热点跟踪,使用频繁就会保存起来
静态方法是也在栈帧里面吗?????
逃逸分析为什么快????
异常处理表??? 出现异常了,异常处理表
oom 和栈溢出区别
混合模式,
直接内存,元空间(直接内存) 直接内存会挤压堆, 2面性
一个进程只能开启一个虚拟机吗
静态属性和静态方法 ,
当不持有引用的时候可以使用静态方法
深入分析对象的内存布局
JVM–详解虚拟机字节码执行引擎之静态链接、动态链接与分派
2019-04-16 jvm
内存分配与回收策略
深入理解垃圾回收器
1.jvm垃圾回收及案例分析
- 学习垃圾回收的意义,
- java与C++之间的区别:
GC
- 谁需要垃圾回收
栈=不需要,凡是共享的对象
堆-重点, 方法区,元空间(也有)
- GC要做的事
- 为什么我们要去了解GC和内存分配?
堆里面继续划分
eden
from Survivor
To Survivor
ODEGEn , 堆 -xmn
回收效率低,就抛出了oom GC overhead limit exceeded
交换区 是 1:1的比列
两个交换区始终占两份,所以,当eden为2时, 就是 2:1:1
-XX:SurvivorRatio =8
引用计数:JVM早期使用
A == > B (1)
C ==> B (1+1)=2
取消引用 -1 引用+1
缺点,
相互引用
A ==》 B 同时 b ==》 a 很难判断是不是该回收 (PHP在使用)
可达性算法(java)
GC Roots 是因为多加了个 s
1.方法区:类静态属性的对象
2.方法区:常量
3.虚拟机栈(本地变量表)中的对象 (方法没完)
本地栈jni对象
只要方法没跳出来,就是gc roots
new 出来的都是强引用
软引用:softreference 当系统要oom了,就会去回收
–图片使用内存,然后要oom要释放了
System.gc主动回收 //gc会消耗性能
-XX:+printGCDetails
弱引用:
弱引用只要垃圾回收,就会被回收
weakHashMap
ThreadLocal 线程隔离
虚引用:PhantomReference 用得非常少 jvm层开发容易用到,回收了会告诉你我要回收了,回收会通知你一下
新生代:
复制回收算法,每次只能用一半
利用率只有一半,
实现简单,运行高效
内存复制,没有内存碎片
90%的对象不需要进行主动回收,10% 8:1:1
很多对象不用去主动回收,使用完了,就释放了
8:1:1?????理解
是取eden里面的对象,是通过对象在serviver区间的移动
90%对象会被回收,10%不回收,所以复制只有10%
空间担保:放不下了怎么办
标记-清除算法,会产生内存碎片
标记-整理算法,内存移动,一定会涉及到效率问题 效率一般般
minor GC FUllGc
1m只是数据,所有大约占据1.5m空间,对象头和填充
新生代会带一些头的信息所以大一些
新生代为什么会大一点????
老年区实际大小差不多???
GC的时候才会去交互区吗
eden存新创建的对象
eden经过回收,就去交换区
eden快满了,就触发GC,然后就交换区间复制
堆内存的分配策略:
- 对象优先在Eden分配 一开始这个区分配
- 大对象直接进入老年代 (eden区放不下,就相当于大对象)
- 长期存活的对象进入老年代
- 动态年龄判断判断
- 空间担保
gc触发条件,就是空间不够了
分带收集:
Serial 单线程
cms 老年代,标记清除算法, (效率很好,空间碎片严重,主流移动互联网用的多)
GC的时候,出来GC线程,会把所有的线程暂停
CMS垃圾回收器工作示意图
cms给予并行收集与并发收集的
并发标记,和用户线程一起进行的
COncMarkSweep
怎么设置自己的项目使用哪个收集器。
初始标记 — 暂停
并发标记 — 同时进行
重新标记 — 暂停
并发清除 — 同时进行
有浮动垃圾
jps -v 看垃圾回收命令
G1垃圾回收器是 1.7提出来的, 可预测性停顿
标记整理 + 化整为零
垃圾回收,都有个内存停顿
吞吐量 = cpu时间 100% gC 10% 业务线程90% 业务线程/总的时间
内存不够了,垃圾回收不成功了,所以就oom了
需要的分配空间不够了,
gc回收不了了,还有对象要进来
内存泄漏,
MAT GC ROOT 引用的线程是否在频繁调用, monitor
Leakcanary, 代码可以追踪内存
空间不够了,就触发GC