第五章 JVM
5.1 初识JVM
5.1.1 JDK、JRE和JVM
工具集(上图最上面一行):
java能运行.class文件,javac能够编译我们的源码文件,jar打包......
Java有句话:
Write once, run anywhere!
JVM可以屏蔽一些操作系统的区别
5.1.2 源码到类文件
比如我们先准备一个Person.java
执行
javac Person.java
会在目录下面得到一个class文件
JVM只认class文件
JVM是java的一个进程
但是打开会发现全部是乱码
可以借助sublime(因为class文件是一个二进制的流文件)
16进制
5.1.3 机制
类加载机制:类文件怎么交给jvm去运行
5.1.4 类加载器
5.2 运行时数据区
5.2.1结构
有些数据是和java虚拟机进程一起的,创建而创建,销毁而销毁
有一些是随着线程在一起的
5.2.2 方法区
由于多个线程都是从方法区获取数据,方法区是线程非安全的
5.2.3 堆
一切皆对象,所以堆的内存占用最大
5.2.4 Java虚拟机栈
上面两个都是进程的,接下去的是线程的
(补充:比如int a = 1;是和对线一起存储在堆里的,因为并不属于常量所以不存储在方法区)
如何描述许多线程跑的状态呢?
溢出会报错:非常经典的StackOverFlow
栈帧
有点抽象,举个例子:
在刚才的目录下执行:
javap -c Person,class > Person.txt
(jdk自带的反编译工具)
比如这个两数相加的cal方法:
Person文件代表的字节码指令:
原来的代码:
仔细看这张图!看完你就懂了
两个加的数字先从操作数栈弹出,再相加放回操作数栈,然后再弹出,赋值给局部变量表
5.2.5 程序计数器
线程暂时失去cpu执行权, 下次还需要从这个地方开始执行
5.2.6 本地技术栈
5.3 JVM内存模型
5.3.1 模型
内存分布:
堆:3000MB
Old:2000MB
Eden:800MB
S0:100MB
S1:100MB
策略:
1、Old区存GC>15的(一般是15)
2、Young区对象一般朝生夕死
3、对象先进来到Eden区,到Eden区不够放就会触发GC,回收掉一些没有用的对象,这时候会有个问题,就是内存空间不连续,这时候会将GC后剩下的对象存放到S0,然后等下一波GC,Eden区的第二轮没被回收的和S0的一起被放到S1。S0和S1反复进行......
4、新进来的对象太大,“担保机制”,Eden区向Old区借地方
5.3.2 Young区
换取10%的空间是为了解决空间碎片的问题
5.3.3 Eden区
不够分配新的对象,就会频繁触发GC,占用线程
5.3.4 Survivor区
5.3.5 结合工具体验和验证
java自带的工具+插件
设置一个一直重复造对象的函数
也可以通过一些命令,下面会有,控制每个区域的大小
超过内存就报错
5.4 垃圾回收
5.4.1 如何判断一个对象是垃圾
5.4.2 分代收集算法
会有空间碎片的问题
会有一半的空间不能用
5.4.3 垃圾收集器
(号称<10ms,了解即可)
5.4.4 有关知识
5.5 工欲善其事必先利其器
5.5.1 JVM参数
比如java -version不随版本变化而变化的,就是标准参数
-x参数:
-xx参数:
其他:
或者java -jar 的时候跟在后面
5.5.2 JVM命令
jsp
jinfo
jstat
jmap
5.5.3 常用工具
jconsole
jvisualvm上面说了
arthas:差不多,命令行交互式界面
mat/perfma(per er ma)
5.6性能优化
5.6.1 OOM
可以用mat定位oom
5.6.2 GC优化
打开GC日志
看吞吐量和停顿时间
用gceasy看
5.6.3 性能优化
5.7 一些问题
根据[gupao云课程]ke.gupaoedu.cn/person/home…以及自己的总结所写,侵删