java虚拟机参数和垃圾回收算法学习记录

来源:互联网 发布:gns3端口8000被拒绝 编辑:程序博客网 时间:2024/04/28 09:16

最近学习了解了虚拟机参数设置以及一些垃圾回收算法, 记录下来方便后面学习和查询 .


虚拟机参数

  • 参数规范
    (1)-XX是对系统级别的(JVM)配置, 配置日志信息, 或者配置JVM使用怎样的垃圾回收机制
    (2)非-XX 类型的是对应用层面的配置
    (3) “+” 表示启用 “-” 表示禁用

  • 各类参数

    • -Xms : 设置java程序启动时初始堆大小
    • -Xmx : 设置java程序能获得最大堆大小
    • -XX:+PrintGC : 使用这个参数, 虚拟机启动后, 只要遇到GC就会打印日志
    • -XX:+UseSerialGC : 配置串行化回收器
    • -XX:+PrintGCDetails : 可以查看详细信息, 包括各个区情况
    • -Xmn : 设置新生代大小, 设置一个比较大的新生代会减少老年代的大小, 这个参数对系统性能以及GC行为有很大影响, 新生代大小一般会设置整个堆空间的1/3或1/4大小作用.
    • -XX: SurvivorRatio : 用来设置新生代中eden空间和from/to空间的比例, 含义: -XX:SurvivorRatio=eden/from=eden/to . 比如新生代设置100M, 如果eden/from = 2, 那么eden会占50M, from占25M, to占25M . from和to区域一般相同.
    • -XX:NewRatio : 设置新生代和老年代比例, -XX:NewRatio=老年代/新生代 .
  • 注意点
    • 新生代设置太大 : 会占据老年代的空间, 应用程序执行中中, 经常使用的是老年代里的对象, 并且频繁使用多次 . 老年代变小会导致FullGC频繁执行 .
    • 新生代设置太小 : 那么一批对象刚创建, 由于新生代太小, 会直接放到老年代 , 由于老年代GC算法和新生代不同,老年代的GC一般是full GC, 非常耗性能 .
    • -XX:SurvivorRatio设置过大 :意味着Eden区域变大, minorGC次数降低, 但两块S区域变小, 如果超过S区域内存大小对象在minorGC后仍没被使用, 会直接进入老年代 .
    • -XX:SurvivorRatio设置过小 : 意味着Eden区域变小, minorGC触发次数增加, S区域变大, 意味着可以存储更多minorGC后仍存活对象, 避免进入老年代 .
    • 合理设置对象在新生代存或周期 : 新生代存活周期据定了新生代对象经过多少次的MinorGC进入老年代, JVM参数对这个值对应是 -XX:MaxTenuringThreShold, 默认是15
    • 不同堆分布情况, 对系统执行会产生一定影响, 实际工作中根据系统特点做出合理配置, 基本策略 : 尽可能将对象预留在新生代, 减少老年代GC次数 , 老年代GC次数很耗性能 .

垃圾回收算法

常见垃圾收集算法:

引用计数法 : 古老算法, 核心就是在对象呗其他所引用时计数器加1, 二挡引用失效时就减1, 但是这种算法有一个很严重的问题 : 无法处理循环引用情况, 还有就是每次进行加减操作比较耗费性能 .
标记清除法 : 分为标记和清除两个阶段进行处理内存中的对象,使用根集概念,基于tracing算法从根开始扫描,识别出哪些对象可达哪些不可达, 当然这种方式有很大弊端, 就是空间碎片问题, 垃圾回收空间不是连续的, 不连续的内存空间的内存效率低于连续的内存空间 .
复制算法 : 核心就是将内存空间分为两块, 每次只使用其中一块, 在垃圾回收时, 将正在使用的内存中存留对象复制到未被使用的内存块中, 之后清除之前正在使用的内存块中对象 . 反复交换两个内存角色, 完成垃圾收集.( java中新生代的from和to空间就是使用这个算法, 可以将内存收集)
标记压缩法 : 标记压缩法在标记清除基础做了优化, 把存活对象压缩到内存一端, 而后进行垃圾清除(java中老年代使用的就是标记压缩法) .
genneration算法 : 复制算法唯一缺陷是收集器必须复制所有活动对象, 增加程序等待时间, 这是复制算法效率低下原因, 程序设计中有这样规律: 多数对象的存活时间较短, 少数存活时间长, 因此, gen算法将堆分为两个或者多个, 每个子堆作为对象的一代, 由于多数对象存在时间比较短, 随着程序丢弃不使用的对象, 垃圾收集器将从最年轻的子堆中收集这些对象, 在分代式垃圾回收器执行后, 上次存活下来的对象会移动到下一个高级的自对中, 由于老一代子堆不经常被回收, 因此节约了时间 .

genneration算法:

  • 年轻代 :
    • 所有新生成对象首先都放在年轻代, 年轻代目标就是尽可能快速收集掉生命周期短的对象 .
    • 新生代内存一般按照 8:1:1 比例分为一个eden区和两个survivor (survivor0, survivor1 )区, 一个eden区, 两个Survivor. 大部分对象在eden区中生成, 回收后将eden区存活对象复制到一个survivor0区, 然后清空eden区, 当这个survivor0存放满了, 将eden区和s0区存活对象(刚才s0不一定是满的了,可能经历过几次GC)复制到另一个s1区中, 然后清空eden区和s0, 此时s0是空的, 然后将s0和和s1交换, 即保持s1区为空, 如此往复 .
    • 当s1区不足存放eden和s0的存活对象时, 就将存活对象直接放到老年代, 如果是老年代也满了, 就会发生一次Full GC, 也就是新生代老年代都进行回收 .
    • 新生代的Gc叫Minor GC, MinorGC频率比较高 .
  • 老年代 :
    • 在年轻代经历N次垃圾回收后仍然存活的对象, 就会被放到老年代中, 因此可以认为老年代存放的都是生命周期比较长的 .
    • 老年代内存比新生代大很多, 当老年代存放满会触发Full GC, Full GC发生频率比较低, 老年代存活时间较长, 存活率比较高 .
0 0
原创粉丝点击