本文共 5089 字,大约阅读时间需要 16 分钟。
1、什么是JVM?
1)机器码翻译(翻译.class文件到机器指令的一个转换)
2)内存管理(因为JVM提供了内存管理功能,让开发人员只需要去关注代码逻辑开发就可以。)
Java程序的跨平台特性主要是指字节码文件可以在任何具有Java虚拟机的计算机或者电子设备上运行,Java虚拟机中的Java解释器负责将字节码文件解释成为特定的机器码进行运行。因此在运行时,Java源程序需要通过编译器编译成为.class文件。
2、为什么要学习JVM?
是因为程序出现内存溢出、内存泄漏的问题时候,我们是一无所知的,我们的内存管理已经交给JVM了,所以我们要学习JVM
3、运行时数据区
程序计数器:指向当前线程正在执行的字节码指令的地址、行号
虚拟机栈:存储当前线程运行方法所需要的数据、指令、返回地址
本地方法栈:带native修饰的方法就是本地方法,没有实现类(c、c++实现)
存储当前线程运行本地方法所需要的数据、指令、返回地址
方法区:类信息(类的原信息)、常量(1.7)、静态变量、JIT(运行时动态生产的代码class)
Heap堆:存放的是对象、数组等
JMM:内存模型:
新生代采用复制回收算法:
系统中对象的生命周期不一样,所以heap内存才会进行分代存储
新生代为什么分为3块,并且比例为8:1:1?
98%的对象在新生代区进行young Gc(minor Gc)的时候会被回收掉,不能回收掉的放在s1里面
新生代和老年代的默认比例是1:2
什么样的对象需要呗GC?
JVM对象分配?
1、通过cas机制去开辟空间,保证所有线程开辟空间同步执行(指针碰撞,内存规整)
2、free list 空闲列表
栈上分配:TLAB: thread local ALLACTION BUFFER 栈上分配,jvm为每一个线程在eden单独开辟一个空间,存储对象
可以通过-XX:+UseTLAB 来设置大小
堆:
-Xms20M starting 堆的起始大小 -Xmx max 堆的最大大小 -Xmn new 堆的新生代大小
对象分配eden,指定新生代eden、s0、s1分配比例
-XX:SurvivorRatio=8 8:1:1对象很大
-XX:PretenureSizeThreshold=3145728 3M 长期存活的对象,age -XX:MaxTenuringThreshold=15 动态对象年龄判定 相同年龄所有对象的大小总和 > Survivor空间的一半 分配担保 Minor GC 之前检查老年代最大可用连续空间是否>新生代所有对象总空间 Minor GC 新生代eden区 Major GC 老年代old区 Full GC minor Gc + Major Gc 什么样的对象需要回收? 回收 方法论 标记-清除算法:出现的比较早,效率不高,需要去标记,空间碎片,不是连续空间 复制-回收算法:实现简单、高效,直接复制,复制后是连续的,缺点是浪费空间 标记-整理算法:连续空间,没有碎片,效率不高单线程和多线程快?
8核多线程快
垃圾收集器
STW Stop The World Serial(新生代):单线程回收 ParNew (新生代):多线程回收,充分的资源利用率 -XX:ParallelGCThreads 控制回收多线程的个数 Parallel Scavenge (全局)(新生代) 吞吐量 = 运行用户代码时间 / (运行用户代码时间 + 垃圾收集时间) -XX:MaxGCPauseMillis=n GC停顿时间 -XX:GCTimeRatio=n GC时间 -XX:UseAdaptiveSizePolicy GC Ergonomics 减少垃圾收集时间 Serial Old(老年代) CMS备用预案 Concurrent Mode Failusre时使用 标记-整理算法 Parallel Old(老年代) 标记-整理算法 CMS(老年代) 标记-清除算法 减少回收停顿时间 碎片: -XX:CMSInitiationgOccupancyFraction Concurrent Mode Failure 启用Serial Old -XX:+UseCMSCompactAtFullCollection Full GC的时候,要不要开启压缩 -XX:CMSFullGCsBeforeCompaction 执行多少次不压缩FullGC后 来一次带压缩的 0 表示每次都压 -XX:+UseConcMarkSweep 设置CMS算法 G1:分块,复制回收、标记清楚算法,会选择垃圾最多的区块进行优先回收 回收的时间节点?安全点?
安全点:执行比较久的过程之前或者之后,来做一个停顿,这个点就是安全点
方法调用之前或者之后、循环跳转、方法跳转、异常跳转
1、抢占式:当Gc线程需要执行的时候,应用线程会检查自己是否在安全点上,如果再就stop the world
2、主动式中断:如果垃圾回收器进行回收操作的时候,会设置一个标识,应用线程执行的时候,去检查标识,如果标识存在就停止,等待标识去除后,再进行应用的调用
安全区域?
就是GC线程执行的过程,如果线程在安全区域,则线程可以继续执行
如何查看当前使用的是什么垃圾回收器?
-XX:+PrintFlagsFinal 将垃圾收集器打印到启动日志中
-XX:+PrintCommandLineFlags server client MBean GC日志 1.输出日志 -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xloggc:/home/administrator/james/gc.log -XX:+PrintHeapAtGC 2.日志文件控制 -XX:-UseGCLogFileRotation -XX:GCLogFileSize=8K 3.怎么看 JDK自带的 监控工具 https://docs.oracle.com/javase/8/docs/technotes/tools/windows/toc.html jmap -heap pid 堆使用情况 jstat -gcutil pid 1000 GC数据统计jstat -gccause pid 1000 GC引起的原因
jstack 查看线程dump jvisualvm jconsole MAT http://help.eclipse.org/oxygen/index.jsp?topic=/org.eclipse.mat.ui.help/welcome.html -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/administrator/james/error.hprof怀疑:
1.看GC日志 126719K->126719K(126720K) 2.dump 3.MAT 1.占用Retained Heap 2.看有没有GC Root指向 VM参数 http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html什么条件触发STW的Full GC呢?
Perm空间不足; CMS GC时出现promotion failed和concurrent mode failure(concurrent mode failure发生的原因一般是CMS正在进行,但是由于老年代空间不足,需要尽快回收老年代里面的不再被使用的对象,这时停止所有的线程,同时终止CMS,直接进行Serial Old GC); (promontion faild产生的原因是EDEN空间不足的情况下将EDEN与From survivor中的存活对象存入To survivor区时,To survivor区的空间不足,再次晋升到old gen区,而old gen区内存也不够的情况下产生了promontion faild从而导致full gc )统计得到的Young GC晋升到老年代的平均大小大于老年代的剩余空间;
主动触发Full GC(执行jmap -histo:live [pid])来避免碎片问题。
java -Xms8m -Xmx64m -verbose:gc -Xloggc:/home/administrator/james/gc.log -XX:+PrintHeapAtGC -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCTimeStamps -XX:+PrintCommandLineFlags -XX:+PrintFlagsFinal -XX:+PrintGCDetails -XX:+UseConcMarkSweepGC -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=9004 -Djava.rmi.server.hostname=177.1.1.122 -jar jvm-demo1-0.0.1-SNAPSHOT.jar > catalina.out 2>&1 &java -Xms128m -Xmx128m -verbose:gc -Xloggc:/home/administrator/james/gc.log -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/administrator/james/error.hprof -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCTimeStamps -XX:+PrintCommandLineFlags -XX:+PrintFlagsFinal -XX:+PrintGCDetails -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=9004 -Djava.rmi.server.hostname=177.1.1.122 -jar jvm-demo1-0.0.1-SNAPSHOT.jar > catalina.out 2>&1 &
java -Xms128m -Xmx128m -verbose:gc -Xloggc:/home/administrator/james/gc.log -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintHeapAtGC -XX:HeapDumpPath=/home/administrator/james/error.hprof -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCTimeStamps -XX:+PrintCommandLineFlags -XX:+PrintFlagsFinal -XX:+PrintGCDetails -XX:+UseCMSCompactAtFullCollection -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=9004 -Djava.rmi.server.hostname=177.1.1.122 -jar jvm-demo1-0.0.1-SNAPSHOT.jar > catalina.out 2>&1 &-XX:+CMSScavengeBeforeRemark
死锁对系统的影响?系统资源是有限的,浪费系统资源
转载地址:http://bxlci.baihongyu.com/