jvm原理(学习)

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负荷越低越好

猜你喜欢

转载自zhanghteye.iteye.com/blog/2372908