JVM参数和查看本机默认参数
-Xms: 设置堆的最小空间大小。
-Xmx: 设置堆的最大空间大小。
-Xmn: 设置新生代最大内存大小(比列也有冲突的话,以这个为准--显式指出)。
-XX:NewRatio: 设置新生代与老年代的比例,默认是2。
-XX:SurvivorRatio: 设置新生代中Eden区于Survivor区的比例。
-XX:-UseAdaptiveSizePolicy: 关闭自适应的内存分配策略(+是开启,-是关闭)。
-XX:NewSize: 设置新生代最小空间大小。
-XX:MaxNewSize: 设置新生代最大空间大小。
-XX:MaxTenuringThreshold=<N>: 设置新生代幸存者1区或2区晋升到老年代(原空间)的年龄计数器阈值--默认15。
-XX:UseTLAB: 默认开启TLAB空间,-XX:TLABWasteTargetPercent设置TLAB占用Eden的百分比。
-XX:+DoEscapeAnalysis: 显示开启逃逸分析。
-XX:+PrintEscapeAnalysis: 查看逃逸分析的筛选结果。
-XX:+EliminateAllocations: 开启代码优化之标量替换。
-XX:PermSize: 设置永久代最小空间大小。
-XX:MaxPermSize: 设置永久代最大空间大小。
-Xss: 设置每个线程的堆栈大小。
windows--cmd命令:
jps: 列出当前正在运行的Java进程的进程ID和主类名称
jinfo -flag NewRatio 12088: 获取指定Java进程的 NewRatio (设置新生代和老年代的比例一半默认为2)参数值的命令
jstat -gc 10716: 是一个用于监视指定Java进程的垃圾回收统计信息的命令,或者通过jvisualvm进行可视化监控(需下载GC插件)
新生代(S0、S1)、Eden空间(EC)、老年代(OC)、元数据空间(MC)等的容量和使用情况,以及年轻代垃圾回收次数(YGC)和时间(YGCT)、Full GC 次数(FGC)和时间(FGCT)等
JVM常用调优工具
-
JDK:jinfo,jstat,javap,jmap荡下文件导入到Memeory Analyzer Tool分析
-
Jconsole,jvisualvm(jdk自带),Jprofiler(idea下载插件)
jps
(JVM Process Status): 类似 UNIX 的ps
命令。用于查看所有 Java 进程的启动类、传入参数和 Java 虚拟机参数等信息;jstat
(JVM Statistics Monitoring Tool): 用于收集 HotSpot 虚拟机各方面的运行数据;jinfo
(Configuration Info for Java) : Configuration Info for Java,显示虚拟机配置信息;jmap
(Memory Map for Java) : 生成堆转储快照;jhat
(JVM Heap Dump Browser) : 用于分析 heapdump 文件,它会建立一个 HTTP/HTML 服务器,让用户可以在浏览器上查看分析结果;jstack
(Stack Trace for Java) : 生成虚拟机当前时刻的线程快照,线程快照就是当前虚拟机内每一条线程正在执行的方法堆栈的集合。
垃圾回收器知识点
频繁在新生代回收,很少在老年代回收,几乎不在永久代/元空间收集!!
Eden区放不下执行YGC,YGC会顺带执行幸存者区的垃圾回收,如果幸存者区还放不下就直接晋升为老年代,如果老年代放不下,执行Full GC或者Major GC
当Eden区满的时候出发YGC或者Minor GC顺带回收幸存者区的垃圾,达到一定条件晋升
幸存者1区和2区采用垃圾回收算法:1:1复制算法,解决碎片化问题 == 复制之后有交换,谁空谁是to ==
基于HotSpot VM的实现:部分收集器(Partial GC),整堆收集器(Full GC),STW:暂停用户线程,需要等待
Minor GC:Eden满的时候触发,Survivor满不会触发,GC整个年轻代。特点:朝生夕灭,频繁,速度快
Major GC:老年代空间不足时先触发Minor GC,再触发Major GC,之后内存还不足就OOM了
Full GC:调用System.gc()时--不必然,老年代不足,方法区不足,Minor GC后平均大小大于Old可用内存,开发中尽量避免
很多时候,Major GC会和Full GC混合使用!--G1 GC
JVM调优
减少垃圾回收的次数(减少用户的STW等待时间),重点是fullGC和majorGC--是minor GC的10倍以上
JVM面试知识点
TLAB:Thread Local Allocation Buffer:Eden区内开辟--每个线程分配一个私有缓冲区。(堆空间都是共享的吗?X-->还有线程私有的TLAB)
堆是对象内存分配的唯一选择吗?
代码优化方面:实际上是字节码文件加载到内存中以后,才执行优化。字节码还存在代码
-
让对象在堆内的分配少一些(TaoBaoVM),生命周期较长的对象分配到栈上--栈上分配--避免堆上的垃圾回收
栈上分配要经过逃逸分析:一个对象并没有逃逸出方法的话,那么可能被优化成栈上分配了。new的一个对象只在方法内部使用
举例--return sb(逃逸);--return sb.toString()(不逃逸,在内部把StringBuffer使用了,没有发生逃逸);
理解:new的对象实体可能在方法外调用,开发中能使用局部变量的尽量避免在方法外定义
-
同步省略:同步(synchronize)只能被一个线程访问,一个对象但是在方法内部,加同步没有意义,所以JIT编译器会同步消除掉。
-
分离对象或标量替换:经过逃逸分析后,发现定义的标量(栈中栈帧的局部变量中)把定义的对象拆解成若干个成员变量来替换。
-
方法区:字符串常量池,其中存在数量值,字符串值,属性引用,方法引用,符号引用(加载的父类,print Stream等 #54,#55,就是各种调相关常量池中的调用)
-
方法区中主要进行垃圾回收的两部分内容:常量池中废弃的常量(没有没直接引用)和不在使用的类型。
-
static修饰会在编译阶段加载,初始化值会在连接的准备阶段,static final则会在编译阶段加载和初始化值。
-
运行时常量池具备动态性:例如String的intern()方法会在常量池中校验有没有,没有的会加载到字符串常量池中
-
-
对象实例化的几种方式:
1. new:最常见的方式,变形1:单例模式下调用Xxx的静态方法(可见的无参构造方法)变形2:工厂模式XxxBuilder/XxxFactory的静态方法。
2. Class的newInstance():反射的方式,因为比较苛刻-只能调用空参的构造器,权限是public,在jdk1.9之后废除。
3. Constructor的newInstance(Xxx):反射的方式,可以调用空参、带参的构造器,权限没有要求。
4. 使用clone():不调用任何构造器,当前类实现Cloneable接口,实现clone方法。
5. 使用反序列化:从文件中、网络中获取一个对象的二进制流,可以反序列化一个对象。
6. 第三方库Objenesis
-
StringTable(字符串常量池):为什么会调整?元空间-->堆空间,触发永久代的回收效率很低,多数情况下是OLD区空间不足或永久代不足的Full GC 导致大量的字符串创建,回收效率低,永久代内存不足。
-
StringTable:涉及到的面试常用点
-
String的基本特性:字符串," "引起来,声明为final,不可被继承(已经很完备了),char数组转byte数组,节省空间
-
String的不可变性:字符串常量池中是不会存储相同内容的字符串的
-
String str1 = "javaEE";
String str2 = "hadoop";
String str3 = "javaEEhadoop";//都是常量的话直接编译器会优化,最终引用地址指向同一个字符串常量
String str4 = str1+"hadoop" / "javaEE"+str2 / str1+str2;
只要拼接符号的前后出现变量,则相当于在堆空间中new一个对象(开辟了一个新的空间,引用一个新的地址)
str1+str2执行的细节:(注意!!变量拼接才会这样,如果用final修饰(变量就不是变量--是常量了),常量的引用也会被编译器优化)
①StringBuilder s = new StringBuilder();
②s.append("a");
③s.append("b");
④s.toString() ---> 约等于new String("ab");
-
new String()到底创建了几个对象:两个对象--一个对象是:new关键字在堆空间创建的,另一个对象是:字符串常量池中的对象。字节码指令:ldc
⭐重点记忆⭐Java源程序经过编译后生成字节码文件,字节码文件通过类的加载器加载到运行时数据区,针对于字节码文件中的数据我们就会有一个具体的分配,针对于类信息本身存放在方法区中,针对于字节码文件执行的过程中,比如new对象了(在堆空间中),方法的调用的时候,在虚拟机栈中分配一个个的栈帧,在整个执行过程中也会用到方法计数器来计数(来记录整个线程当中代码执行到哪一行了),主要在方法区中放的是类信息,运行时常量池(字符串常量)
线程私有的:PC程序计数器、本地方法栈、虚拟机栈。
虚拟机栈中的每个栈帧又分为返回值,本地局部变量表,操作数栈,动态链接(执行运行时常量池中的方法引用,哪个具体的方法)
方法区中的常见垃圾回收:常量池中废弃的常量和不在使用的类型。