《深入理解java虚拟机》之虚拟机优化案例

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lyzx_in_csdn/article/details/83473419

    1、高性能硬件上的程序部署策略

      服务运行一段时间后发现,网站会出现长时间的卡顿,
        分析原因:一次Full GC要用14s的时间,网站会加载大文件到内存中,这些大对象直接进入老年代
                没有在Minor GC中清理掉,即使有12G的内存,依然会被很快占用完
            
            如果使用64位JDK 使用高内存配置需要考虑的问题
                1、较长的内存回收时间导致的卡顿
                2、需要保证程序足够稳定,否则无法生成并分析dump文件
                3、相同的程序64位JDK比32位JDK消耗的内存大
            解决方案:多部署几个较低配置的服务并使用nginx代理(基本可以解决问题)
                此方案的缺点:
                    连接池,缓存难以共享,需要消耗更多的资源

    
    2、集群间同步导致的内存溢出


    3、堆外内存导致的内存溢出

   堆外内存值jvm直接使用的操作系统的内存,这部分内存叫做堆外内存,
        情况描述:应用程序莫名抛出内存溢出异常,而通过jstat观察内存情况发现一切正常,则此时很可能就是堆外内存溢出
        堆外内存的回收策略:在垃圾回收器回收老年代内存时,即发生FullGC的时候会"顺便"回收堆外内存,
        但是每个应用程序管理的内存是有限的,
        所以,堆外内存和虚拟机的堆栈等内存是此消彼长的关系
        堆外内存不会在该区域内存使用完时通知垃圾回收器回收垃圾,
        而只是调用System.gc(),如果此时垃圾回收器
        依然没有回收该区域的内存,那么就会抛出内存溢出
        可以通过使用NIO申请堆外内存即直接内存(Direct Memory)
        使用内存较大的区域:
            1、通过NIO申请的堆外内存
            2、线程堆栈 通过-Xss参数控制
            3、Socket缓冲区(Receive和send)


    4、外部命令导致系统缓慢

 java使用RunTIme.getRunTime().exec()创建外部进程时开销特别大,
 这个命令的执行过程是:首先虚拟机克隆一个和当前虚拟机拥有一样环境变量的虚拟机,
 再使用这个克隆的虚拟机执行外部命令
 然后再关闭克隆的这个虚拟机


    5、服务器JVM进程崩溃
      

 情况描述:
            通过系统调用另外一个系统的服务,此时是长连接,但是另一个系统的服务返回时间较长,在这个过程中连接关闭,
            由于外部系统的服务速度跟不上导致过多的线程和Socket连接太多最终jvm崩溃
        解决方案:把外部系统的调用改为消息队列/进程之间的观察者模式

猜你喜欢

转载自blog.csdn.net/lyzx_in_csdn/article/details/83473419