zoukankan      html  css  js  c++  java
  • JVM垃圾回收(GC)原理

    一.基本垃圾回收算法

    1.引用计数(Reference Counting)

    比较古老的回收算法。原理是此对象有一个引用则增加一个引用计数,删除一个引用则较少一个引用计数。垃圾回收时,只回收引用计数为0的对象。此算法最致命的是无法处理互相引用的问题。

     

    2.标记-清除(Mark-Sweep)

    此算法执行分两个阶段。第一个阶段是从根节点开始标记所有被引用的对象;第二个阶段遍历整个堆,把未标记的对象清除。此算法需要暂停整个应用,并且会产生内存碎片。

     

    3.复制(Copying)

    此算法把内存空间划分为2个相同的区域,每次只使用其中一个区域。垃圾回收时,区域A从根开始访问每一个关联的正在使用的对象,并且把正在使用的对象复制到另外一个区域B,然后回收区域A中所有对象。此算法只访问活跃对象,所以遍历空间成本低,但是此算法的缺点也很明显,就是需要2倍内存空间。

     

    4.标记-整理(Mark-Compact)

    此算法也是分两个阶段。第一个阶段是从根节点开始标记所有被引用的对象;第二阶段遍历整个堆,清除未被标记的对象并且把标记的对象(正在使用的对象)压缩到一起按顺序存放。此算法避免了“标记-清除”算法中的内存碎片问题,并且也避免了“复制”算法的空间问题。

     

    二.JVM内存模型。

    1.基础概念

    (1)JVM内存限制(最大值):

    JVM内存的最大值跟操作系统有很大的关系。简单的说32位操作系统虽然可控内存有4GB,但是操作系统会给一个限制,Windows下为2GB,Linux下为3GB,而64位及以上的操作系统没有限制。

    (2)JVM默认内存分配:

    JVM初始分配的内存由-Xms指定:默认是物理内存的1/64但是小于1GB。

    JVM最大分配的内存有-Xmx指定:默认是物理内存的1/4但是小于1GB。

    (3)JVM内存自动调整:

    默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx限制,可以由-XX:MinHeapFreeRatio=指定。

    默认空余堆内存大于70%时,JVM就是减少堆直到-Xms限制,可以由-XX:MaxHeapFreeRatio=指定。

    但是服务器一般都设置-Xms、-Xmx相等以避免每次gc后都调整堆的大小,所以这两个参数一般没什么作用。

     

    2.堆(Heap)和非堆(Non-heap)内存 

    (1)堆(Heap)

    (2)非堆(Non-heap)

    参考文档:

    http://www.cnblogs.com/redcreen/tag/jvm/

    http://chenchendefeng.iteye.com/blog/455883

    http://www.open-open.com/lib/view/open1324736648468.html

    http://vanadiumlin.iteye.com/blog/1267857

    JVM参数:

    1、JVM堆相关参数

    参数 说明 备注
    -Xmx

    设置最大堆内存

    一般-Xmx与-Xms设置相同

    -Xms

    设置最小堆内存

     
    -Xmn

    设置新生代内存大小

    -Xmn等同于设置了相同的-XX:NewSize与-XX:MaxNewSize

    -XX:NewSize

    设置新生代初始大小

     
    -XX:MaxNewSize 设置新生代最大值  
    -XX:PermSize 设置持久代初始大小 用于JDK8 之前
    -XX:MaxPermSize 设置持久代的最大值 用于JDK8 之前
    -XX:MetaspaceSize 设置持久代初始大小 用于JDK8之后,包含JDK8
    -XX:MaxMetaspaceSize 设置持久代的最大值 用于JDK8之后,包含JDK8
    -Xss 设置线程栈的大小 线程栈所占内存不是堆内存,是操作系统内存减去堆内存
    -XX:MinHeapFreeRatio 设置堆空间最小空闲比例 当堆空间的空闲内存小于这个数值时,JVM便会扩展堆空间,默认值40
    -XX:MaxHeapFreeRatio 设置堆空间最大空闲比例 当堆空间的空闲内存大于这个数值时,JVM便会压缩堆空间,得到一个较小的堆,默认值70
    -XX:NewRatio 设置老年代与新生代比例 等于老年代大小除以新生代大小
    -XX:SurviorRatio 新生代中Eden与survivor区的比例  
    -XX:TargetSurvivorRatio 设置survivor区的使用率 当survivor区的空间使用率达到这个数值时,会将对象送入老年代,默认值50,最高90
         

    2、JVM垃圾收集器相关参数

    参数 说明 备注
     -XX:+CMSClassUnLoadingEnabled  允许对类元数据进行回收  
     -XX:CMSInitiatingPermOccupancyFraction  当永久代占用率达到这一百分比时,启动CMS回收  前提是-XX:+CMSClassUnLoadingEnabled激活了
     -XX:UseCMSInitiatingOccupancyOnly  表示只在达到阈值的时候,才进行CMS回收  
     -XX:+CMSIncrementalMode  使用增量模式,比较适合单CPU  

    3、实用JVM参数

    参数 说明 备注
    -XX:+HeapDumpOnOutOfMemoryError 当程序发生OOM时,导出应用程序当前堆快照  
    -XX:HeapDumpPath 可以指定堆快照的保存位置

    -XX:+HeapDumpOnOutOfMemoryError
    -XX:HeapDumpPath=/Users/yangyu/Downloads

    -XX:OnOutOfMemoryError 系统发生OOM错误时可运行一段第三方脚本

    -XX:OnOutOfMemoryError=c: eset.bat

    -verbose:gc 获取gc信息  
    -XX:+PrintGC 获取gc信息  
    -XX:+PrintGCDetails 获取gc详细信息  
    -XX:+PrintHeapAtGC gc时打印详细的堆信息  
    -Xloggc 将gc信息保存到文件 -Xloggc:/Users/yangyu/Downloads/gc.log
    -XX:+TraceClassLoading 用于跟踪类加载情况  
    -XX:+TraceClassUnLoading 用于跟踪类卸载情况  
    -verbose:class 用于跟踪类加载和卸载情况  
    -XX:+DisableExplicitGC 用于禁止显示的gc操作 也就是禁止代码里面的System.gc()
  • 相关阅读:
    L1-050 倒数第N个字符串 (15分)
    Oracle存储过程的疑难问题
    Linux的细节
    Linux字符设备和块设备的区别
    Shell变量
    游标的常用属性
    Oracle中Execute Immediate用法
    Oracle中的sqlerrm和sqlcode
    Oracle把一个表的数据复制到另一个表中
    Oracle的差异增量和累积增量
  • 原文地址:https://www.cnblogs.com/eoss/p/5981461.html
Copyright © 2011-2022 走看看