3.1.2 JVM性能调优-垃圾回收机制

什么是垃圾回收机制

C/C++语言 是手动来回收堆内存里不再使用的对象,而JAVA则是由JVM来自动回收

如何确定内存需要被回收了

标记 ,标记正在使用的内存,不在使用的内存,其中有2种内存

  • 对象内存回收,即堆内存的回收,使用可达性分析算法来回收
  • 方法区回收 这一节没有细说

可达性算法

可达性算法有一个根GCRoots,然后将所有相关的对象与它相连,如果某个对象在某个时候不可达到GCroots,那么它就可以被回收

具体的算法实现

所有的都是基于标记--清除这一算法的,然后有2种改进型

  1. 标记-清除 优点:快 缺点:有内存碎片问题(就是内存虽然还有很多空间,但却不连续,实际上是不能存储数据的)
  2. 标记-复制-清除: 优点:解决了碎片问题 缺点:占用空间
  3. 标记-清除-整理 在1的基础上,将内存整理成连续的 缺点:慢

具体的JVM实现

可以看到以上三种方法各有利弊,所以JVM实现的时候,在不同的场景使用不同的方法

分代收集

JVM大多数会使用分带收集实现,即新生代-次新生代-次次新生代--老生代
大概的算法就是

  1. 新建的对象放在新生代,使用标记-清除 这种方法,速度快
  2. 经历一次GC的,给它累加一个计数器,然后放到次新生代
  3. 当一个对象经历了数次GC,计数器累加到一定的次数时,JVM认为他经常使用,所以放到老生代,老生代使用标记-清除-整理的方法
  4. 空间大的对象也会直接放到老生代
    经历多少次放到老生代,多大的对象会放到老生代,这些都是可以用参数来设置的

收集器

并行收集器

跟串行收集器的区别就是新生代GC和老生代GC一起进行,可以设置GC时间和吞吐量等值,可以自动进行适应性调整Eden,Surviror大小和MaxTenuringThreshold大小,感觉可以简单理解成多线程了

吞吐量 用户代码运行时间/(用户代码运行时间+GC时间)
可以设置的参数
  • -XX:ParallelGCThreads 设置用于垃圾回收的线程数。通常情况下可以和CPU数量相等
  • -XX:MaxGCPauseMills 设置最大垃圾收集停顿时间。它是一个大于0 的证书
  • -XX:GCTimeRatio 设置吞吐量大小,它是一个0-100之间的整数
  • -XX:UseAdaptiveSizePolicy: 打开自使用GC策略,达到在对大小、吞吐量和停顿时间之间的平衡

ParallelScavenge和Parallel Old

服务器模式默认使用这个并发收集器,它有年轻代和老年代两个实现

并行收集器G1

JDK1.9后默认的收集器,不区分年轻代和老年代的实现


截屏2019-12-07下午5.36.28.png

你可能感兴趣的:(3.1.2 JVM性能调优-垃圾回收机制)