jvm原理(学习)
程序计数器、java虚拟机栈、本地方法栈,线程私有。
方法区、java堆:线程公有。
栈:保存参数、局部变量、中间计算过程和其他数据。
方法区:类信息,常量池,静态字段,方法
堆:java对象
方法区物理上存在于堆上,在堆的持久代里面;逻辑上,方法区跟堆是独立的。
jvm堆配置参数
1、-Xms 初始化堆大小 默认物理内存的1/64(<1G)
2、-Xmx最大堆大小 默认物理内存的1/4(<1G)实际应用不建议大于4G
3、一般建议设置-Xms=-Xmx,好处避免每次gc后,调整堆大小,减少系统内存分配开销
4、整个堆大小=年轻代大小+年老代大小+持久代大小
jvm新生代
1、新生代=1个eden区+2个Survivor区
2、-Xmn,新生代大小,默认为堆的3/8
3、-XX:NewRatio:新生代与年老代的比值,Xms=Xmx并且设置了Xmn的情况下,改参数不需进行设置
4、-XX:SurvivorRatio:Eden区与Survivor区大小比值,默认为8,2个S:1个E=2:8,一个Survivor区占新生代的1/10
5、新生代用来存放JMV刚分配的Java对象
jvm老年代
1、年轻代中经过垃圾回收没有回收掉的对象被复制到老年代
2、老年代存储对象比年轻带年龄大的多,而且不乏大对象
3、新建d对象也有可能直接进入老年代(大对象超过-XX:PretenureSizeThreshold=1024,直接进入老年代)
4、老年代大小无需参数配置
java持久代(方法区)
1、-XX:PermSize -XX:MaxPermSize,建议配置相同值,因为永久代大小的调整也会导致堆内存需要触发GC。
2、存放Class、Method元信息,一般设置为128M,设置原则是预留30%的空间。
3、回收方式:
常量池中的常量、无用的类信息,常量的回收很简单,没有引用就回收。
对无用的类进行回收,必须保证3点:
类的所有实例都已经被回收
加载类的ClassLoader已经被回收
类对象的Class对象没有被引用(即没有通过反射引用该类的地方)
jvm垃圾收集算法:
1、引用计数算法(JKD1.2之前)
2、根搜索算法
jvm垃圾回收算法
1、复制算法(一般用于新生代内存回收)
2、标记清除算法(适用在存活对象比较多,但会造成内存碎片)
3、标记整理压缩算法(基于标记清除算法,对对象进行移动,解决碎片问题)
并行:指两个或者多个事件在同一时刻发生。
并发:指两个或者多个事件在同一时间间隔发生。
串行回收:是指gc单线程内存回收,会暂停所有用户线程。(serial收集器是串行的)
并行回收:是指多个GC线程并行工作,但此时用户线程是暂停的。(Parallel收集器是并行的)
并发回收:是指用户线程与GC线程同时执行(不一定是并行,可能交替,但总体上是同时执行的),不需要停顿用户线程(其实在CMS收集器中用户线程还是需要停顿的,只是非常短,GC线程是在另一个CPU上执行)
JVM常见垃圾回收器:Serial、Parallel、CMS,三个又分别分新生代回收、老生代回收。
Serial回收器(串行回收器)
1、是一个单线程的收集器,只能使用一个CPU或者一条线程去完成垃圾收集;
进行垃圾收集时,必须暂停所有其他工作线程,直到收集完成。
2、缺点:Stop-The-World
3、优势:简单,对于单CPU的情况,由于没有多线程交互开销,反而可以更高效,是Client模式下默认的新生代收集器。
新生代Serial回收器
1、-XX:+UseSerialGC来开启
Serial New + Serial Old的收集器组合进行内存回收
2、使用复制算法
3、独占式的垃圾回收。
一个线程进行GC,串行。其他工作线程暂停。
老年代Serial回收器
1、-XX:+UseSerialGC来开启
Serial New + Serial Old的收集器组合进行内存回收
2、使用标记-压缩算法
3、串行的、独占式的垃圾回收器。
因为内存比较大原因,回收比新生代慢
ParNew回收器(并行回收器)
并行回收器也是独占式的回收器,在收集过程中,应用程序会全部暂停。但由于并行回收器使用多线程进行垃圾回收,因此,在并发能力比较强的CPU上,它产生的停顿时间要短于串行回收器,而在单CPU或者并发能力较弱的系统中,并行回收器的效果不会比串行回收器好,由于多线程的压力,它的实际表现很可能比串行回收器差。
新生代ParNew回收器
1、-XX:+UseParNewGC开启
新生代使用并行回收收集器,老年代使用串行收集器。
2、-XX:ParallelGCThreads指定线程数
默认最好跟CPU数量相当,避免过多的线程影响垃圾收集性能。
3、使用复制算法。
4、并行的、独占式的垃圾回收期。
新生代Parallel Scavenge回收器
1、吞吐量优先回收器
关注CPU吞吐量,即运行用户代码的时间/总时间,比如:JVM运行100分钟,其中运行用户代码99分钟,垃圾收集1分钟,则吞吐量是99%,这种收集器能最高效率的利用CPU,适合运行后台运算。
2、-XX:+UseParallelGC开启
使用Parallel Scavenge+Serial Old收集器组合回收垃圾,这也是在Server模式下的默认值。
3、-XX:GCTimeRatio
来设置用户执行时间占总时间的比例,默认99,即1%时间用来进行垃圾回收
4、-XX:MaxGCPauseMillis
设置GC的最大停顿时间
5、使用复制算法
老生代Parallel Old回收器
1、-XX:+UseParallelOldGC开启
使用Parallel Scavenge + Parallel Old组合收集器进行收集
2、使用标记整理算法
3、并行的、独占式的垃圾回收器
GC性能指标
吞吐量:应用花在非GC上的时间百分比
CG负荷:应用花在GC上的时间百分比
暂停时间:CG stop-the-world时间
GC频率
反应速度:从对象变成垃圾到被回收的时间
交互式应用:要求暂停时间越少越好
非交互式应用:要求GC负荷越低越好
实时系统:要求暂停时间、GC负荷越低越好