|
1内存区域
线程共享:堆,方法区
线程独占:本地方法栈(native),虚拟机栈,程序计数器
以下会出现内存溢出(OutOfMemoryError)
当 虚拟机栈扩展时,内存不足。
堆中没有完成实例的分配,且堆也无法扩展的时候。
方法区无法满足内存分配的需求时,运行时常量池无法再申请到内存时
直接内存(NIO类的分配方式,在jvm之外,只是用native函数库方法直接分配的堆外内存,用java堆中的DirectByteBuffer来操作这块内存的引用)和各个内存区域总和大于物理内存。
堆存放对象,数组
方法区存放类加载的信息,常量,静态变量。
虚拟机栈,与线程生命同周期,描述的是java方法执行的内存模型,每个方法执行时会创建一个栈祯,用于存储局部变量表,操作数栈,动态链接,方法出口等信息。
2GC
GC算法在其他博客中写出。
OopMap 数据结构用来在类加载完成的时候,HotSpot就把对象内什么偏移量上是什么类型的数据计算处理啊, 在JIT编译过程中,也会特定的位置记录下栈和寄存器中哪些位置是引用。
GC触发的抢险式是让所有暂停,发现不再安全点上的线程继续跑。(不可取)
主动式是让所有线程执行到安全点(一个内存页设置为不可读,线程执行到该指令处就会产生一个自陷的异常信号,在预先注册的异常处理器中暂停线程实现等待),就触发gc。
安全域的引用关系不会发生变化,是为了解决某些线程sleep或者blocked状态,导致线程无法达到安全点,=在这个区域中的人和地方GC都是安全的。
垃圾收集器:
Serial 最早的,单线程收集器, 高效。
ParNew是 Serial的多线程版本(单cpu下的线程交互开销大,不划算)。
Parallel Scavenge 关注的是吞吐量 = 代码执行时间/(代码执行时间+GC时间) (代码执行时间/CPU总耗时间),该垃圾收集器,关注两个东西,吞吐量和最大停顿时间。可设置-XX:UseAdaptiveSizePolicy动态调整新生代区域比例划分以及晋升老年代年龄等,系统收集监控信息,动态调整出最合适的停顿时间或最大吞吐量,只需要给出一个参数,您是要关注最大暂停时间(MaxGCPauseMillis),还是吞吐量(GCTimeRatio)。
以上三个都是对于新生代区域的堆内存回收垃圾收集器。
CMS 并发收集器, 初始标记和重新标记是需要 Stop the world,但时间很短很短, 时间运行更长的是 并发标记和并发清理, 都是与用户线程并发进行的,所以程序不会有明显的停顿。作用于老年代。该老年代使用标记-清除算法,
参数说明,大部分搜集于其他博文与JVM性能调优书籍
堆设置
-Xms:初始堆大小
-Xmx:最大堆大小
-XX:NewSize=n:堆中新生代内存大小
-XX:NewRatio=n:设置年轻代和年老代的比值。如:为3,表示年轻代与年老代比值为1:3,年轻代占整个年轻代年老代和的1/4
-XX:SurvivorRatio=n:年轻代中Eden区与两个Survivor区的比值。注意Survivor区有两个。如:3,表示Eden:Survivor=3:2,一个Survivor区占整个年轻代的1/5
-XX:MaxPermSize=n:设置持久代大小
-XX:MaxTenuringThreshold=n survivor区对象最大存活年龄
收集器设置
-XX:+UseSerialGC:设置串行收集器
-XX:+UseParallelGC:设置并行收集器
-XX:+UseParalledlOldGC:设置并行年老代收集器
-XX:+UseConcMarkSweepGC:设置并发收集器
-XX:+UseCMSCompactAtFullCollection:使用并发收集器时,开启对年老代的压缩。
-XX:CMSFullGCsBeforeCompaction=0:上面配置开启的情况下,这里设置多少次Full GC后,对年老代进行压缩,因为老年代使用标记清除算法,会产生大量内存碎片,需要整理。
并行收集器Paralle设置(关注最大吞吐量与最大停顿时间)
-XX:ParallelGCThreads=n:并行收集线程数。此值最好配置与处理器数目相等。
-XX:MaxGCPauseMillis=n:设置并行收集最大暂停时间
-XX:GCTimeRatio=n:设置垃圾回收时间占程序运行时间的百分比。公式为1/(1+n)
垃圾回收统计信息
-XX:+PrintGC 开启打印GC功能。
-XX:+PrintGCDetails 打印GC回收的详细信息。
-XX:+PrintGCTimeStamps 打印GC停顿耗时。
-Xloggc:filename
|