JVM内存分配与回收分析

 java虚拟机的自动化内存可以归结为自动化解决了两个问题,一个是内存分配,一个是内存回收。了解虚拟机的分配与回收机制,能让我们对项目的把控更加有力,尤其是对性能调优时,

各个参数的设置可能会有意想不到的效果。本文结合事例分析各种场景的回收。

  堆内存区域(不包括永久代)种类:1,eden space(属于新生代-new generation)

          2,survivor space(属于新生代-new generation)

          3,tenured generation(年老代)

  首先解释下各参数的含义。我们可以通过run -> run configuration 中选择argument 中的VM arguments来输入参数调节个参数值。

    -Xms20m : 代表给堆分配20m的初始内存

    -Xmx50m : 代表堆的最大分配内存为50m

    -Xmn10m : 代表给新生代(new generation)分配10m的内存

    -Xss128k:每个线程最大堆栈内存

       -XX:PermSize=10M : 给永久代分配10M内存

    -XX:MaxPermSize=100M:永久代最大内存为100M

           -XX:MaxDirectMemorySize=10M:直接内存最大为10M

           -XX:+PrintGCDetails:控制台输出GC信息

    -XX:SurvivorRatio=8:新生代(new generation)中eden区与survivor区分配的比例为8:1

     -XX:PretenureSizeThreshold=2m:对象内存大小超过这个直接放入年老区(tenured generation)

     -XX:MaxTenuringThreshold=3:代表对象在三次后即第四次GC会进入年老区(tenured generation)

 

  分配策略一:对象优先在eden中分配 

    配置信息:-Xmx20m -Xms20m -Xmn10m -XX:+PrintGCDetails -XX:SurvivorRatio=8

    代码:

复制代码
public class Allocation {
    
    public static final int _1MB = 1024*1024;
    public static void main(String[]args)
    {
        byte[] allocation1,allocation2,allocation3,allocation4,allocation5;
        
        allocation1 = new byte[4*_1MB];
    }
}
复制代码

  执行结果:

复制代码
Heap
 def new generation   total 9216K, used 4831K [0x331d0000, 0x33bd0000, 0x33bd0000)
  eden space 8192K,  58% used [0x331d0000, 0x33687fd0, 0x339d0000)
  from space 1024K,   0% used [0x339d0000, 0x339d0000, 0x33ad0000)
  to   space 1024K,   0% used [0x33ad0000, 0x33ad0000, 0x33bd0000)
 tenured generation   total 10240K, used 0K [0x33bd0000, 0x345d0000, 0x345d0000)
   the space 10240K,   0% used [0x33bd0000, 0x33bd0000, 0x33bd0200, 0x345d0000)
 compacting perm gen  total 12288K, used 145K [0x345d0000, 0x351d0000, 0x385d0000)
   the space 12288K,   1% used [0x345d0000, 0x345f4468, 0x345f4600, 0x351d0000)
    ro space 10240K,  42% used [0x385d0000, 0x38a14240, 0x38a14400, 0x38fd0000)
    rw space 12288K,  54% used [0x38fd0000, 0x39654d58, 0x39654e00, 0x39bd0000)
复制代码

  我们逐行分析,第二行:显示了,我们给新生代分配了9216K内存(这个由于XX:SurvivorRatio参数不同,会有小幅变动,总体接近10M)

       第三行:显示了eden代分配了8912k,并且58%被使用,这个就是程序中新加入的对象放到了新生代中,刚好是4M

       第四行,第五行,两个值默认是一样,是指survivor区的大小,8192:1024刚好是XX:SurvivorRatio=8的8:1

                   第六行:年老代,10240k,总共分配了20M的堆,新生代占了10M,那么年老代就是10M

       后面的则是永久代信息,这边暂不讨论。

  从上面的代码,执行结果,以及分析中,我们能看出最初的对象是分配在eden space中的。

  当然如果eden满了,则会分配到suvivor space 和tenured generation 中,如:

复制代码
public class Allocation {
    
    public static final int _1MB = 1024*1024;
    public static void main(String[]args)
    {
        byte[] allocation1,allocation2,allocation3,allocation4,allocation5;
        
        allocation1 = new byte[2*_1MB];
        allocation2 = new byte[2*_1MB];
        allocation3 = new byte[2*_1MB];
        //第四次分配不足,出发gc
        allocation4 = new byte[4*_1MB];
    }
}
复制代码

执行结果:

复制代码
[GC [DefNew: 6716K->378K(9216K), 0.0038688 secs] 6716K->6522K(19456K), 0.0038989 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
Heap
 def new generation   total 9216K, used 4802K [0x331d0000, 0x33bd0000, 0x33bd0000)
  eden space 8192K,  54% used [0x331d0000, 0x33621fa0, 0x339d0000)
  from space 1024K,  36% used [0x33ad0000, 0x33b2e940, 0x33bd0000)
  to   space 1024K,   0% used [0x339d0000, 0x339d0000, 0x33ad0000)
 tenured generation   total 10240K, used 6144K [0x33bd0000, 0x345d0000, 0x345d0000)
   the space 10240K,  60% used [0x33bd0000, 0x341d0030, 0x341d0200, 0x345d0000)
 compacting perm gen  total 12288K, used 145K [0x345d0000, 0x351d0000, 0x385d0000)
   the space 12288K,   1% used [0x345d0000, 0x345f44a0, 0x345f4600, 0x351d0000)
    ro space 10240K,  42% used [0x385d0000, 0x38a14240, 0x38a14400, 0x38fd0000)
    rw space 12288K,  54% used [0x38fd0000, 0x39654d58, 0x39654e00, 0x39bd0000)
复制代码

  经历了一次GC,信息中显示了各个内存区域的使用情况

 

  分配策略二:大对象直接进入老年代

    配置信息:-Xmx20m -Xms20m -Xmn10m -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:PretenureSizeThreshold=3m

    代码:

复制代码
public class Allocation {
    
    public static final int _1MB = 1024*1024;
    public static void main(String[]args)
    {
        byte[] allocation1,allocation2,allocation3,allocation4,allocation5;
        
        allocation4 = new byte[4*_1MB];
    }
}
复制代码

  执行结果:

复制代码
Heap
 def new generation   total 9216K, used 735K [0x331d0000, 0x33bd0000, 0x33bd0000)
  eden space 8192K,   8% used [0x331d0000, 0x33287fc0, 0x339d0000)
  from space 1024K,   0% used [0x339d0000, 0x339d0000, 0x33ad0000)
  to   space 1024K,   0% used [0x33ad0000, 0x33ad0000, 0x33bd0000)
 tenured generation   total 10240K, used 4096K [0x33bd0000, 0x345d0000, 0x345d0000)
   the space 10240K,  40% used [0x33bd0000, 0x33fd0010, 0x33fd0200, 0x345d0000)
 compacting perm gen  total 12288K, used 145K [0x345d0000, 0x351d0000, 0x385d0000)
   the space 12288K,   1% used [0x345d0000, 0x345f4468, 0x345f4600, 0x351d0000)
    ro space 10240K,  42% used [0x385d0000, 0x38a14240, 0x38a14400, 0x38fd0000)
    rw space 12288K,  54% used [0x38fd0000, 0x39654d58, 0x39654e00, 0x39bd0000)
复制代码

   从结果中可以看出来,eden space,survivor都未分配内存,而tenured generation 则分配了4096k,即4M大小超过了XX:PretenureSizeThreshold=3M限制,直接进入老年代

 

  分配策略三:长期存活的对象将进入年老代

    jvm在管理内存时,会把存活时间长的对象放入年老代,没经历一次GC存活下来的的对象,他的age加1,

    参数:-Xmx20m -Xms20m -Xmn10m -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=1

    代码:

复制代码
public class Allocation {
    
    public static final int _1MB = 1024*1024;
    public static void main(String[]args)
    {
        byte[] allocation1,allocation2,allocation3,allocation4,allocation5;
        
        allocation1 = new byte[1*_1MB/4];
        allocation2 = new byte[4*_1MB];
        allocation3 = new byte[4*_1MB];
        allocation3 = null;
        allocation3 = new byte[4*_1MB];
    }
}
复制代码

    执行结果:

复制代码
[GC [DefNew: 4924K->633K(9216K), 0.0030944 secs] 4924K->4729K(19456K), 0.0031222 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC [DefNew: 4893K->0K(9216K), 0.0009591 secs] 8989K->4729K(19456K), 0.0009776 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
Heap
 def new generation   total 9216K, used 4260K [0x331d0000, 0x33bd0000, 0x33bd0000)
  eden space 8192K,  52% used [0x331d0000, 0x335f8fd8, 0x339d0000)
  from space 1024K,   0% used [0x339d0000, 0x339d0088, 0x33ad0000)
  to   space 1024K,   0% used [0x33ad0000, 0x33ad0000, 0x33bd0000)
 tenured generation   total 10240K, used 4729K [0x33bd0000, 0x345d0000, 0x345d0000)
   the space 10240K,  46% used [0x33bd0000, 0x3406e6d0, 0x3406e800, 0x345d0000)
 compacting perm gen  total 12288K, used 144K [0x345d0000, 0x351d0000, 0x385d0000)
   the space 12288K,   1% used [0x345d0000, 0x345f4270, 0x345f4400, 0x351d0000)
    ro space 10240K,  42% used [0x385d0000, 0x38a14240, 0x38a14400, 0x38fd0000)
    rw space 12288K,  54% used [0x38fd0000, 0x39654d58, 0x39654e00, 0x39bd0000)
复制代码

    从上面中,我能看到,在第二次GC中,第二行 [DefNew: 4893K->0K(9216K) 新生代全部清为0,都放到年老代中去了,因为他们的age已经为2,超过-XX:MaxTenuringThreshold=1的限制。

   当然GC的内存分配与回收策略有很多中,而且对于不同的GC回收器,回收机制也不一定一样,上面讲的三种回收机制,使用较广泛,我们可以在eclipse等ide工具中实践。通过不断的调

节与实践,会使自己对GC以及JVM更加了解。

以下是对提供的参考资料的总结,按照要求结构化多个要点分条输出: 4G/5G无线网络优化与网规案例分析: NSA站点下终端掉4G问题:部分用户反馈NSA终端频繁掉4G,主要因终端主动发起SCGfail导致。分析显示,在信号较好的环境下,终端可能因节能、过热保护等原因主动释放连接。解决方案建议终端侧进行分析处理,尝试关闭节电开关等。 RSSI算法识别天馈遮挡:通过计算RSSI平均值及差值识别天馈遮挡,差值大于3dB则认定有遮挡。不同设备分组规则不同,如64T和32T。此方法可有效帮助现场人员识别因环境变化引起的网络问题。 5G 160M组网小区CA不生效:某5G站点开启100M+60M CA功能后,测试发现UE无法正常使用CA功能。问题原因在于CA频点集标识配置错误,修正后测试正常。 5G网络优化与策略: CCE映射方式优化:针对诺基亚站点覆盖农村区域,通过优化CCE资源映射方式(交织、非交织),提升RRC连接建立成功率和无线接通率。非交织方式相比交织方式有显著提升。 5G AAU两扇区组网:与三扇区组网相比,AAU两扇区组网在RSRP、SINR、下载速率和上传速率上表现不同,需根据具体场景选择适合的组网方式。 5G语音解决方案:包括沿用4G语音解决方案、EPS Fallback方案和VoNR方案。不同方案适用于不同的5G组网策略,如NSA和SA,并影响语音连续性和网络覆盖。 4G网络优化与资源利用: 4G室分设备利旧:面对4G网络投资压减与资源需求矛盾,提出利旧多维度调优策略,包括资源整合、统筹调配既有资源,以满足新增需求和提质增效。 宏站RRU设备1托N射灯:针对5G深度覆盖需求,研究使用宏站AAU结合1托N射灯方案,快速便捷地开通5G站点,提升深度覆盖能力。 基站与流程管理: 爱立信LTE基站邻区添加流程:未提供具体内容,但通常涉及邻区规划、参数配置、测试验证等步骤,以确保基站间顺畅切换和覆盖连续性。 网络规划与策略: 新高铁跨海大桥覆盖方案试点:虽未提供详细内容,但可推测涉及高铁跨海大桥区域的4G/5G网络覆盖规划,需考虑信号穿透、移动性管理、网络容量等因素。 总结: 提供的参考资料涵盖了4G/5G无线网络优化、网规案例分析、网络优化策略、资源利用、基站管理等多个方面。 通过具体案例分析,展示了无线网络优化中的常见问题及解决方案,如NSA终端掉4G、RSSI识别天馈遮挡、CA不生效等。 强调了5G网络优化与策略的重要性,包括CCE映射方式优化、5G语音解决方案、AAU扇区组网选择等。 提出了4G网络优化与资源利用的策略,如室分设备利旧、宏站RRU设备1托N射灯等。 基站与流程管理方面,提到了爱立信LTE基站邻区添加流程,但未给出具体细节。 新高铁跨海大桥覆盖方案试点展示了特殊场景下的网络规划需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值