虚拟机、字节码、平台无关
JVM内存分配
栈内存分配:栈调优 -XSS
堆内存变量:保存对象
JVM堆配置参数:
-Xms 初始堆大小 默认物理内存的1/64(<1GB)
-Xmx 最大堆大小 默认物理内存的1/4(<1GB),实际中建议不大于4G
一般建议设置 -Xms = -Xmx
好处是避免每次在gc之后,调整堆的大小,减少系统内存分配开销
整个堆大小=年轻代大小+年老代大小+持久代大小
新生代=1个eden区+2个Survivor区
-Xmn 年轻代大小
-XX:NewRatio 年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代)
Xms=Xmx并且设置了Xmn的情况下,改参数不需要进行设置
-XX:SurvivorRatio
Eden区与Survivor区的大小比值,用来存放JVM刚分配的Java对象
1、Java老年代=整个堆-年轻代大小-持久代大小
2、年轻代中经过垃圾回收没有回收掉的对象被复制到老年代
3、老年代存储对象比年轻代年龄大的多,而且不乏大对象
4、新建的对象也有可能直接进入老年代(大对象、大的数组对象)可通过启动参数设置
-XX:PretenureSizeThreshold=1024(单位为字节,默认为0)来代表超过多大就不在新生代分配,而是直接在老年代分配。
5、老年代大小无配置参数
Java持久代
1、持久代=整个队-年轻代大小-老年代大小
2、-XX:PermSize -XX:MaxPermSize
设置持久代的大小,一般情况下推荐把-XX:PermSize设置成XX:MaxPermSize的值为相同的值因为持久代大小的调整也会导致堆内存需要触发fgc
3、存放Class、Method元信息
jvm内存垃圾回收:
jvm垃圾收集算法:
1、引用计数算法(已过时)
每个对象有一个引用计数属性,新增一个引用时计数加1,引用释放时计数减1
计数为0时可以回收。方法简单,但是无法解决对象相互循环引用的问题,还
有一个问题是如何解决精准计数。
2、根搜索算法
从GC Roots开始向下搜索,搜索所走过的路径称为引用链。当一个对象到GC
Roots没有任何引用链相连时,则证明此对象是不可用的,不可达对象。
jvm垃圾回收算法:
1、复制算法(copying)对象少时比较高效,需要占用一块内存交换空间用于进行
对象的移动。用于新生代的回收。
2、标记清除算法(Mark-Sweep)不进行对象移动 会有内存碎片问题
3、标记整理压缩算法(Mark-Compac)进行对象移动,成本高,消耗资源,没有内 存碎片问题
1、串行回收
gc单线程内存回收、会暂停所有用户线程
2、并行回收
收集是指多个GC线程并行工作,但此时用户线程是暂停的;所以,Serial是串行的,Parallel收集器是并行的,而CMS收集器是并发的
3、并发回收
是指用户线程与GC线程同时执行,不一定是并行,可能交替,但总体上是在同时执行,不需要停顿用户线程。
Serial回收器 -XX:+UseSerialGC来开启
新生代ParNew回收器:
-XX:+UseParNewGC 新生代使用并行回收收集器,老年代使用串行收集器
-XX:ParallelGCthreads 指定线程数
新生代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、并行的、独占式的垃圾回收器
CMS(并发标记清除)回收器:
运行分为4各阶段:
初始标记(CMS initial mark) 只标记GC Roots能直接关联到的对象
并发标记(CMS concurrent mark)进行GC Roots Tracing的过程
重新标记(CMS remark)修正并发标记期间因用户程序继续运行而导致标记发 生的那一部分对象的标记
并发清除(CMS concurrent sweep)
其中标记和重新标记连个阶段任然需要Stop-The-World,整个过程中耗时最长的并发标 记和并发清除过程中收集器都可以和用户线程一起工作