上一篇地址:https://blog.csdn.net/weixin_46635575/article/details/122684355
下一篇地址:https://blog.csdn.net/weixin_46635575/article/details/122740245
一、各大垃圾回收器
1、Minor GC(也就是YGC)
其实进行性能优化,其实可以片面的理解是当垃圾回收的次数比较少。因为我们的垃圾回收器触发后,会消耗时间,而且Major GC和Full GC触发后的时间会是YGC的时间的10倍以上。调优是尽可能的少出现上面两种。
YGC它是会在我们的当我们的新生代中的Eden满后,就会触发这个垃圾回收器。
STW其实可以理解为:我们的垃圾回收也就是一个线程在执行,它执行垃圾标记的时候,它会让其他线程停止对内存的访问。
2、Major GC(也就是Old GC)
老年代的回收器
3、Full GC
- full的中文意思相信各位都知道,满了就进行回收。
- 它是整堆回收(包括堆和我们方法区)
4、上面三个的关系
5、GC举例与分析日志
- 先设置代码
- 查看效果和分析
这个fullGC是的metaSpace在jdk8及后才会有,之前的jdk是没有的。
YGC时间是用得比较少的
二、堆空间分代思想
- 其实就一个目的,不管jdk怎么划分,它的目的都是为了方便进行垃圾回收。
三、内存分配策略
四、堆内容补充
1、TLAB
- 为什么要TLAB
- 到底上面是TLAB
- 对象分配过程
经过上面的分析为什么我们在堆区的数据区并不是全部共享的。
2、堆空间的参数设置
- 都是在这个位置设置
- 一个个的分析一下
主要的是我们的新生代不要占比太大,如果太大的话,可能我们的YGC失去意义了。
同样的如果新生代确定,而Eden设置比较叫时,它会出现的频率变高,也会提高STW的次数增多,这样我们的频率高,性能变差。 - 最后还有点的是担保的问题。
3、问题(堆是分配对象内存的唯一选择吗)
- 到底什么是逃逸呢?看对比就会发现了
-
没发生(像这种没有返回的,在自己内部使用,完了就不存在了),它就可以在栈上分配。
-
发生了(其实就判断这个对象是否被外部调用),就不能在栈上分配
-
- 开启逃逸分析
- 结论:咱们能定义局部变量就在方法内,就不要去方法外去定义(就是不要定义为一个属性),用完了就OK了,不然性能可能会影响性能。
(1)代码优化之栈上分配
看例子(减号就是没有开启逃逸分析)
它的执行速度相比较是变慢了。
如果开启了的话
- 不会发生GC
- 速度快很多。
(2)代码优化之同步省略
(3)代码优化之分离对象或标量替换
- 其实可以理解为变形的栈上分配
五、小结
但是像淘宝的GCIH已经做到了将对象在特殊情况下直接使用内存分配,不适用堆分配。