1.TLAB
TLAB Thread Local Allocation Buffer,JDK1.7默认开启TLAB一般不需要去设置,TLAB极大提高程序性能,它是Java的一个优化方案。
-XX:+UseTLAB 开启TLAB
-XX:+PrintTLAB 打印TLAB信息
-XX:+TLABSize 设置TLAB大小
-XX:TLABRefillWasteFraction 设置维护进入TLAB空间单个对象大小,比例值,默认1/64,对象大于该值会去堆创建。
-XX:ResizeTLAB 自调整TLABRefillWasteFraction 阀值。
![](http://upload-images.jianshu.io/upload_images/1759749-75999692a48c430b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/700)
测试
public static void alloc(){
byte[] b = new byte[100];
byte[] b2 = new byte[100];
}
public static void main(String[] args) {
long begin = System.currentTimeMillis();
for(int i=0; i<200000000;i++){
alloc();
}
System.out.println("耗时"+(System.currentTimeMillis() - begin));
}
配置TLAB的运行结果
-XX:+UseTLAB -XX:+PrintTLAB
![](http://upload-images.jianshu.io/upload_images/1759749-fff09d507cfd2ec2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/700)
配置禁用
-XX:-UseTLAB -XX:+PrintTLAB
![](http://upload-images.jianshu.io/upload_images/1759749-fbac3ba379ff9ce4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/700)
配置TLAB性能高很多,这和对象的安置优先选择的顺序有关系。
2.安置顺序
创建一个对象会尝试在栈上分配,不能分配栈上其次尝试TLAB,再其次是老年代,最后选择是年轻代的Eden,老年代和Eden都是堆内存中。
![](http://upload-images.jianshu.io/upload_images/1759749-48cc2199db2d4d6b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/700)
3.垃圾收集算法
1:引用计数
对象被引用时计数器+1,引用失效时-1,这个算法有一些问题,循环引用情况不好处理,频繁+-操作比较耗费性能。
2:标记清除
分为标记和清除两个阶段处理内存中的对象,这种方式弊端是会产生空间碎片,垃圾回收后的空间不连续。
3:复制
将内存空间分为两块(如from和to),每次使用一块,垃圾回收时,将正在使用的对象复制到另外一个区将可回收的对象留在当前区,再把当前区的对象都回收。
4:标记压缩
在标记清除的基础上做了优化,把存活对象压缩到一端然后进行垃圾清理,老年代中使用的上标记压缩的方法。
5:分代算法
根据对象特点把内存分成多块,而后根据每块内存的特点使用不同的算法。新生代回收频率很高,但是每次回收耗时很短,而老年代回收频率较低耗时比较长,所以会尽量减少老年代的GC。
6:分区算法
将整个内存分成多个独立的空间,每个空间可以独立使用,能够细粒度控制回收那些小空间不用一次把整个内存空间GC。
4.垃圾收集器
垃圾收集器决定了堆内存的格局,有的回收器没有把堆新生代分成eden、from、to是在策略不同,而使用from、to(拷贝、肃清)是为了保证内存空间的连续性。
1:串行垃圾收集器 -XX:+UseSerialGC
使用单线程进行垃圾回收器。每次回收时一个线程工作,对于并行能力较弱的计算机来说,串行回收器的专注性和独占性会有更好的性能表现。串行回收器可以在新生代和老年代使用,根据作用于不同堆空间分为新生代串行回收器和老年代串行回收器。
![](http://upload-images.jianshu.io/upload_images/1759749-cfaeec0e82fd150c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/700)
2:并行垃圾收集器-XX:+UseParNewGC
并行回收器在串行回收器基础上做了改进,它使用多个线程同时进行垃圾回收,对于计算能力强的计算机而言,可以有效的缩短垃圾回收所需的实际时间。
ParNew回收器是一个工作在新生代的垃圾收集器,其是多线程的,但是回收策略和算法同串行回收器一样。配置-XX:ParallelGCThreads
指定线程数量。
![](http://upload-images.jianshu.io/upload_images/1759749-c549380263ca305a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/700)
3:并行回收器-XX:+UseParallelGC
新生代ParallelGC回收器,使用复制算法的收集器,也是多线程独占形式的收集器。ParallelGC回收器非常关注系统的吞吐量。
-XX:MaxGCPauseMillis
设置最大垃圾收集停顿时间,参数设置小了会引起频繁GC会降低吞吐量。
-XX:GCTimeRatio
设置吞吐量大小,是一个百分比(0-100整数),默认情况下99,系统会花不超过1/(1+n)的时间用于垃圾回收,也就是1/(1+99)=1%的时间。
-XX:+UseAdaptiveSizePolicy
设置打开自适应模式,在这种模式下,新生代空间、eden、from/to的比例,以及晋升老年代的对象年龄参数都自动调整,能达到在堆大小、吞吐量和停顿时间之间的平衡点。
![](http://upload-images.jianshu.io/upload_images/1759749-68d84c4646395e73.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/700)
4:并行回收器-XX:+UseParallelOldGC
老年代回收器ParallelOldGC是多线程的回收器,是一个关注吞吐量的回收器,使用标记压缩算法。
-XX:+ParallelGCThreads
配置线程数量。
![](http://upload-images.jianshu.io/upload_images/1759749-a83fd9a41ef90d3b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/700)
5:CMS回收器-XX:+UseConcMarkSweepGC
Concurrent Mark Sweep并发标记清除。
CMS不是独占的回收器,CMS回收过程中程序的其它线程不会停止工作,所以必须保证内存足够使用,如果在CMS工作的时候内存不够使用会回收失败,回收失败时虚拟机会启动老年代串行回收器进行垃圾回收,此时程序会中断。
-XX:CMSInitiatingOccupancyFraction
指定使用内存到一定阀值CMS就会去回收,默认是68(60%)。
-XX:+UseCMSCompactAtFullCollection
设置CMS回收完成后进行一次碎片整理。
-XX:CMSFullGCsBeforeCompaction
设置进行多少次CMS回收之后进行一次内存压缩。
![](http://upload-images.jianshu.io/upload_images/1759749-b931f4fb20d8643b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/700)
6:G1回收器-XX:+UseG1GC
Garbage-First,在Jdk1.7开始出现的垃圾回收器。G1回收器的独特的垃圾回收策略,G1属于分代垃圾回收器,区分新生代和老年代,不要求整个eden区或者新生代、老年代的空间都连续,它使用了分区算法。
G1可多线程工作,G1在工作的时候程序可以正常运行。
G1回收器是分代收集器,但它是兼顾新生代和老年代一起工作。
G1在回收过程中会使用复制对象方式减少空间碎片。
G1由于分区的原因,可以分区进行回收,缩小了回收的范围,提升性能。
-XX:MaxGCPauseMillis
最大停顿时间。
-XX:ParallelGCThreads
线程数量。
![](http://upload-images.jianshu.io/upload_images/1759749-27dfa6a9240ad67a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/700)
作者:ThingLin
链接:https://www.jianshu.com/p/c2b24c5698dd
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。