想要学习JVM调优,咱们必须提早知道他们的一些参数,这样才方便咱们更好的去使用他们html
JVM的命令行参数参考: docs.oracle.com/javase/8/do…java
虚拟机参数分为基本和扩展两类,在命令行中输入 JAVA_HOME\bin\java
就可获得基本参数列表。 在命令行输入 JAVA_HOME\bin\java –X
就可获得扩展参数列表。mysql
-client,-server: 两种Java虚拟机启动方式,client模式启动比较快,可是性能和内存管理相对较差,server模式启动比较慢,可是运行性能比较高,windos上采用的是client模式,Linux采用server模式redis
-classpath -cp: 虚拟机在运行一个类的时候,须要将其转入内存中,虚拟机搜索类的方式和顺序:Bootstrap classes、Extension classes、User classes。 Bootstrap 中的路径是虚拟机自带的 jar 或 zip 文件,虚拟机首先搜索这些包文件,用System.getProperty("sun.boot.class.path")可获得虚拟机搜索的包名。 Extension 是位于 jre\lib\ext 目录下的 jar 文件,虚拟机在搜索完 Bootstrap 后就搜索该目录下的 jar 文件。用 System. getProperty("java.ext.dirs”)可获得虚拟机使用sql
Extension 搜索路径。 User classes 搜索顺序为当前目录、环境变量 CLASSPATH、-classpath。缓存
-classpath: 告诉虚拟机搜索目录名、jar文档名、zip文档名服务器
-verbose[:class|gc|jni]: 在输出设备上显示虚拟机运行信息 -verbose:class 输出虚拟机装入的类的信息 -verbose:gc 在虚拟机发生内存回收时输出设备信息,用来监视虚拟机内存回收的状况 -verbose:jni 虚拟机调用native方法时输出设置显示信息,用来监视虚拟机调用本地方法的状况markdown
-version:显示可运行的虚拟机版本信息并发
-showversion:显示版本信息以及帮助信息oracle
-Xmixed: 设置 -client 模式虚拟机对使用频率高的方式进行 Just-In-Time 编译和执行,对其余方法使用解释方式执行,该方式是虚拟机缺省模式
-Xint: 设置-client模式下运行的虚拟机以解释方式执行类的字节码,不将字节码编译为本机码,有可能会损失性能
-Xbootclasspath:path、-Xbootclasspath/a:path、-Xbootclasspath/p:path: 改变虚拟机装载系统运行包 rt.jar,而从-Xbootclasspath 中设定的搜索路径中装载系统运行类。除非你本身能写一个运行时,不然不会用到该参数。 /a:将在缺省搜索路径后加上 path 中的搜索路径。 /p:在缺省搜索路径前先搜索 path 中的搜索路径。
-Xnoclassgc: 关闭虚拟机对 class 的垃圾回收功能,有可能会致使OutOfMemoryError
-Xincgc: 启动增量垃圾收集器,缺省是关闭的,增量垃圾收集器能减小偶然发生的长时间的垃圾回收形成的暂停时间,但增量垃圾收集器和应用程序并发执行,会占用部分CPU在应用程序上的功能
-Xloggc:file: 将虚拟机每次垃圾回收的信息写到日志文件中,文件名由file指定,文件格式是平文件,内容和-verbose:gc 输出内容相同
-Xms20M: 设置虚拟机可用内存堆的初始大小为20M,大小为1024的整数倍而且要大于1MB,可用K或者M为单位来设置较大内存数,初始堆大小为2MB,例如:-Xms256M
-Xmx20M: 设置虚拟机内存堆的最大可用大小,该值必须为1024的整数倍,而且要大于2MB,可用K或者M为单位来设置较大的内存数,例如:-Xmx81920K,-Xmx80M,当应用程序申请了大内存运行时虚拟机抛出 java.lang.OutOfMemoryError,就须要使用-Xmx来设置了
-Xss128K: 设置线程栈的大小,和-Xmx相似,能够用K或M来设置较大的值,也能够在Java中建立线程对象时设置栈的大小
-Xoss128k: 设置本地方法栈的大小为128K,不过HotSpot不区分虚拟机栈和本地方法栈,因此这个参数对于HotSpot是无效的
-XX:PermSize=10M: 表示JVM初始分配的永久代的容量,必须以M为单位
-XX:MaxPermSize=10M: 表示JVM容许分配的永久代的最大容量,必须以M为单位,大部分状况下这个参数默认为64M
-XX:NewRatio=4: 表示设置年轻代:老年代的大小比值为1:4,这意味着年轻代占整个堆的1/5
-XX:SurvivorRatio=8: 表示设置2个Survivor区:1个Eden区的大小比值为2:8,这意味着Survivor区占整个年轻代的1/5,这个参数默认为8
-Xmn20M: 表示设置年轻代的大小为20M
-XX:+HeapDumpOnOutOfMemoryError: 表示可让虚拟机在出现内存溢出异常时Dump出当前的堆内存转储快照
-XX:+UseG1GC: 表示让JVM使用G1垃圾收集器
-XX:+PrintGCDetails: 表示在控制台上打印出GC具体细节
-XX:+PrintGC: 表示在控制台上打印出GC信息
-XX:PretenureSizeThreshold=3145728 表示对象大于3145728(3M)时直接进入老年代分配,这里只能以字节做为单位
-XX:MaxTenuringThreshold=1: 表示对象年龄大于1,自动进入老年代
标准: - 开头,全部的HotSpot都支持 非标准:-X 开头,特定版本HotSpot支持特定命令 不稳定:-XX 开头,下个版本可能取消
例如:java -version、java -X
import java.util.List;
import java.util.LinkedList;
public class HelloGC {
public static void main(String[] args) {
System.out.println("HelloGC!");
List list = new LinkedList();
for(;;) {
byte[] b = new byte[1024*1024];
list.add(b);
}
}
}
复制代码
区分概念:内存泄漏memory leak,内存溢出out of memory java -XX:+PrintCommandLineFlags HelloGC java -Xmn10M -Xms40M -Xmx60M -XX:+PrintCommandLineFlags -XX:+PrintGC HelloGC PrintGCDetails PrintGCTimeStamps PrintGCCauses java -XX:+UseConcMarkSweepGC -XX:+PrintCommandLineFlags HelloGC java -XX:+PrintFlagsInitial 默认参数值 java -XX:+PrintFlagsFinal 最终参数值 java -XX:+PrintFlagsFinal | grep xxx 找到对应的参数 java -XX:+PrintFlagsFinal -version |grep GC
1. 吞吐量: 用户代码时间 /(用户代码执行时间 + 垃圾回收时间) 2. 响应时间: STW(Stop The World)越短,响应时间越好
所谓的调优,首先本身要明确,想要的是什么,是吞吐量仍是响应时间,仍是在知足必定的响应时间的状况下,要求达到多大的吞吐量,通常来讲根据业务类型去选择对应的调优方式,好比网站须要的是响应时间优先,JDK1.8尽可能选G1,那若是是数据挖掘的须要使用的是吞吐量。
在没有接触过调优以前咱们理解的JVM调优就是解决OOM问题,OOM只是JVM调优的一部分
首先的话,调优是从业务场景开始的,若是没有业务场景的JVM调优都是不靠谱的,好比有时间在实际项目中,有不少个类,成千上万个代码,你怎么知道具体是哪一个代码有问题,就算咱们知道有段代码频繁的full gc,可是可能过一段时间就OOM了。
调优步骤:
熟悉业务场景,选定垃圾回收器(没有最好的垃圾回收器,只有最合适的垃圾回收器)
选择回收器组合
计算内存需求(设置内存大小 1.5G 16G)
选定CPU:越高越好
设定年代大小、升级年龄
设定日志参数
在生产环境中日志文件,后面日志名字,按照系统时间产生,循环产生,日志个数五个,每一个大小20M,这样的好处在于总体大小100M,能 控制总体文件大小
垂直电商,最高每日百万订单,处理订单系统须要什么样的服务器配置
这个问题比较鸡肋,由于不少不一样的服务器配置都可以支撑
好比有一百万个订单,每一个小时不会产生很高的并发量,咱们寻找高峰时间,作一个假设100W订单有72W订单在高峰期产生,好比一个小时平均36W订单,因此咱们内存选择大小是按照巅峰时间选择的,不少时间咱们可能就是去作压测,实在不行就添加CPU和内存
12306遭遇春节大规模抢票应该如何支撑 订单信息天天固定,能够丢到缓存中,不一样的业务逻辑有不一样的业务设计,12306应该是中国并发量最大的秒杀网站,号称并发100W,就是说每秒进行百万次的业务逻辑的处理,估计淘宝一年最高的是54W并发。
若是解决这个问题呢,看下面所示:
CDN -》 LVS -》 NGINX -》 业务系统 -》每台机器1W并发
普通电商的下单流程通常是:
订单 -》下单-》 订单系统减库存 -》 等待用户付款 这个事务若是同步的方式完成,TPS是支撑不了多长时间的
可是在12306里面的模型是 下单-》 减库存和订单同时异步进行 -》 等待付款 异步是当你下完订单以后,它一个线程去减库存,另一个线程直接把你下单的信息扔到kafka或者redis里面直接返回OK,你下单成功后等待你付款,何时你付款完成后面那些个订单处理线程就会去里面拿数据,这个处理完了就会持久化到Hbase或者是mysql,通常大流量的处理方法核心思想就是:分而治之
好比我有一个50万PV的资料类网站(从磁盘提取文档到内存)原服务器32位,1.5G的堆,用户反馈网站比较缓慢,若是对它进行升级,新服务器64位,16G的堆内存,用户仍是反馈卡顿,并且还比以前更严重,这个是由于什么呢?通常来讲不少用户去浏览数据,不少数据会load到内存中,致使内存不足,频繁的GC,STW时间过长,响应时间就会变慢,那咱们应该怎么办呢,使用 PS-> PN+CMS或者G1。
还有一个就是系统CPU常常100%,咱们要如何进行调优呢?
首先咱们能够想到CPU100%那么必定有线程在占用系统资源
- 找出哪一个进程CPU高 (top命令)
- 该进程中的哪一个线程CPU高(top -Hp)
- 导出该线程的堆栈
- 查找哪一个方法(栈挣)比较消耗时间
- 工做线程占比高 | 垃圾回收线程占比高
今天咱们只是讲解了一些基本的操做,具体怎么操做该怎么办呢?这一部分小农会在下一部分中进行讲解,今天主要带你们了解一些经常使用的参数,告诉你们怎么去使用和一些前置知识,下面我会对这些问题作一个实战性的讲解,感兴趣的小伙伴记得来个一键三连,感谢你们。
我是牧小农,怕什么真理无穷,进一步有进一步的欢喜,你们加油!!!