JVM(1) 相关概念及优化

在这里插入图片描述

一、什么是JVM?

​ Java的广告语是”编写一次,到处运行”,而它凭借的就是JVM(Java Virtual Machine).而对于不同的平台,Windows,Linux,Mac OS等,有具体不同的JVM版本.这些JVM屏蔽了平台的不同,提供了统一的运行环境,让Java代码无需考虑平台的差异,运行在相同的环境中.

二、为什么要优化JVM?

​ 我们的Java代码都是运行在JVM中的,而部署的硬件及应用场景有所不同时,仍然采用默认的配置不见得能起到最好的效果,甚至可能会导致运行效率更差,又或者面临高并发情况下,想让程序平稳顺畅的运行,所以我们需要针对实际的需要来进行优化。

三、分析工具

​ 我们只知道有JVM的存在,但它的运行对于我们来说感觉像是摸不着看不见的,所以我们需要借助工具来监控它的一个实时状态,就像Windows的性能监视器一样,JDK也有自己的可视化工具.

cmd执行命令:jvisualvm 启动Java VisualVM

注:

jdk1.8自带VisualVM,但1.9之后需要自己下载:https://visualvm.github.io/download.html

使用IDEA的话,可以下载一个插件:VisualVM Launcher

在这里插入图片描述
在这里插入图片描述

四、JVM组成

在这里插入图片描述

类加载器子系统 (用于类加载的一个子系统)

类加载的过程: 加载,验证,准备,解析,初始化

双亲委派机制:

因为一些类只能有指定的加载来加载
比如java.lang.Object类,如果你放到你自己的classpath下面,这个时候首先找的是应用加载器,没有权限去加载该类,委托上一级去加载,上一级也没权限,找到启动类加载器完成加载 这个就叫双亲委派机制。

在这里插入图片描述

类加载器一般有4种,其中前3种是必然存在的
① 启动类加载器:加载<JAVA_HOME>\lib下的
② 扩展类加载器:加载<JAVA_HOME>\lib\ext下的
③ 应用程序类加载器:加载Classpath下的
④ 自定义类加载器

运行时数据区:方法区 堆 虚拟机栈 本地方法栈 程序计数器

在这里插入图片描述

方法区:
jdk1.7以前 类的信息 常量 静态变量 这个时候方法区也叫永久代 也叫非堆 但是是和堆一起的一块连续的区域
1.7以后 静态变量 字符串常量池移动了堆中
jdk1.8以后 类的信息 编译后的数据放到元空间 占用是本地的内存 方法区没有了
堆内存:存放对象 数组 是垃圾回收的主要区域
堆内存:新生代和老年代
新生代:eden from survivor to survivor
方法区和堆内存都被所有线程共享 在虚拟机启动的时候进行创建

在这里插入图片描述

五、JVM垃圾回收

1、判断对象是否为垃圾的算法

① 引用计数算法
每一个对象都有一个引用计数器,当被外部或者其他对象引用的时候,计数加1,失去引用减1,如果计数器为0的时候,对象等待被回收.但是对象之间可以相互引用,这个时候计数器不为0 而其实对象已经可以被回收了

② 可达性分析算法
通过gcroots 垃圾回收的起点能够找到对象,说明对象还活着,其他不能找对象的就等待被回收;

2、常见垃圾回收算法

① 标记清除算法
对标记的区域进行清理,但是清除出来的内存区域不连续
② 标记复制算法
将内存区域分为两块,一块作为保留区域,当进行垃圾回收的时候,将存活的对象复制到保留区域中并进行排序,使空间连续,而清理出来的区域重新作为保留区域,但是内存空间利用率太低
③ 标记整理算法
一边对已经死掉的对象进行清除,一边对存活的对象进行整理,使内存空间连续
④ 分代算法
新生代由于对象死亡比较快 使用的是标记复制算法
老年代则使用标记清除和标记整理算法

3、垃圾回收时间

当程序运行时,各种数据、对象、线程、内存等都时刻在发生变化,当下达垃圾收集命令后就立刻进行收集吗?肯定不是。这里来了解两个概念:安全点(safepoint)和安全区(safe region)。

安全点:从线程角度看,安全点可以理解为是在代码执行过程中的一些特殊位置,当线程执行到安全点的时候,说明虚拟机当前的状态是安全的,如果有需要,可以在这里暂停用户线程。当垃圾收集时,如果需要暂停当前的用户线程,但用户线程当时没在安全点上,则应该等待这些线程执行到安全点再暂停。举个例子,妈妈在扫地,儿子在吃西瓜(瓜皮会扔到地上),妈妈扫到儿子跟前时,儿子说:“妈妈等一下,让我吃完这块再扫。”儿子吃完这块西瓜把瓜皮扔到地上后就是一个安全点,妈妈可以继续扫地(垃圾收集器可以继续收集垃圾)。理论上,解释器的每条字节码的边界上都可以放一个安全点,实际上,安全点基本上以“是否具有让程序长时间执行的特征”为标准进行选定。

安全区:安全点是相对于运行中的线程来说的,对于如sleep或blocked等状态的线程,收集器不会等待这些线程被分配CPU时间,这时候只要线程处于安全区中,就可以算是安全的。安全区就是在一段代码片段中,引用关系不会发生变化,可以看作是被扩展、拉长了的安全点。还以上面的例子说明,妈妈在扫地,儿子在吃西瓜(瓜皮会扔到地上),妈妈扫到儿子跟前时,儿子说:“妈妈你继续扫地吧,我还得吃10分钟呢!”儿子吃瓜的这段时间就是安全区,妈妈可以继续扫地(垃圾收集器可以继续收集垃圾)。

4、常见垃圾收集器

新生代收集器:Serial、ParNew、Parallel Scavenge
老年代收集器:Serial Old、CMS、Parallel Old
堆内存垃圾收集器:G1
新生代垃圾回收 minor gc
老年代 full gc

六、JVM优化

依据 系统日志 gc日志 堆栈快照
jps
jstat
jmap
可视化工具:jvisualvm

设置jvm参数的几种方式:

1、集成开发环境下启动并使用JVM,如eclipse需要修改根目录文件eclipse.ini;
2、Windows服务器下安装版Tomcat,可使用Tomcat7w.exe工具(tomcat目录下)和直接修改注册表两种方式修改Jvm参数;
3、Windows服务器解压版Tomcat注册Windows服务,方法同上;
4、解压版本的Tomcat, 通过startup.bat启动tomcat加载配置的,在tomcat 的bin 下catalina.bat 文件内添加;
5、Linux服务器Tomcat设置JVM,修改TOMCAT_HOME/bin/catalina.sh;
6、windows环境下配置JAVA_OPT

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

郑清

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值