四:JVM调优与常见异常处理方案

在jvm调优之前,我们必须先了解jvm的内存模型与GC回收机制,这些在我前面的文章里面有介绍!接下来我们通过一个案例来调整jvm性能。

一:调优案例:

  1.1 编写demo

import java.text.DecimalFormat;
/**
    -XX:+PrintGC         GC回收的时候打印相关日志
    -XX:+UseSerialGC     串行回收
    -XX:+PrintGCDetails  显示详细的GC日志

    -Xms               堆初始值
    -Xmx               堆最大可用值
    -XX:SurvivorRatio  新生代中eden空间和from(s0),to(s1)空间的比例.

    -XX:NewRation=   新生带与老年代的比例
    -Xss  栈的大小(栈的深度)
 */
public class JVMDemo {
    public static void main(String[] args) throws InterruptedException {
        // 最大内存
        long maxMemory = Runtime.getRuntime().maxMemory();
        System.out.println("最大堆内存为: "+format(maxMemory)+"MB");
        // 已经使用内存
        long totalMemory = Runtime.getRuntime().totalMemory();
        System.out.println("已使用堆内存: "+format(totalMemory)+"MB");
        // 当前剩余内存
        long freeMemory = Runtime.getRuntime().freeMemory();
        System.out.println("剩余堆内存为: "+format(freeMemory)+"MB");

        byte[] b1 = new byte[4 * 1024 * 1024];
        System.out.println("-----分配了4m堆内存-----");

        // 当前剩余内存
        long freeMemory2 = Runtime.getRuntime().freeMemory();
        System.out.println("剩余堆内存为: "+format(freeMemory2)+"MB");
    }
    /**
     * 将堆内存单位格式化成 MB
     */
    static private String format(long maxMemory) {
        float num = (float) maxMemory / (1024 * 1024);
        DecimalFormat df = new DecimalFormat("0.00");// 格式化小数
        String s = df.format(num);// 返回的是String类型
        return s;
    }
}

  1.2 配置参数,打印jvm信息:  右键 --> Run As --> Run Configurations... --> Arguments --> VM arguments 输入配置信息  -XX:+PrintGCDetails -XX:+UseSerialGC

  

  1.3 运行java代码, 查看jvm信息

// 这些信息与电脑配置参数有关,我们的具体数据可能不一样,但是内存模型数据比例是一样的
最大堆内存为: 1890.81MB  // 大约1900MB
已使用堆内存: 119.88MB   // 已用120MB
剩余堆内存为: 117.89MB   // 剩余117MB
-----分配了4m堆内存-----
剩余堆内存为: 113.89MB   // 用了4mb后还剩113MB
Heap
 def new generation   total 38080K, used 6805K [0x0000000085c00000, 0x0000000088550000, 0x00000000ae800000)
 // 可以看出新生代中默认 eden区 from区 to区比例为 33856:4224:4224 即 8:1:1
  eden space 33856K,  20% used [0x0000000085c00000, 0x00000000862a57a8, 0x0000000087d10000)
  from space 4224K,   0% used [0x0000000087d10000, 0x0000000087d10000, 0x0000000088130000)
  to   space 4224K,   0% used [0x0000000088130000, 0x0000000088130000, 0x0000000088550000)
 // 老年代和新生代默认比例为 84672:(33856+4224+4224)  即2:1
 tenured generation   total 84672K, used 0K [0x00000000ae800000, 0x00000000b3ab0000, 0x0000000100000000)
   the space 84672K,   0% used [0x00000000ae800000, 0x00000000ae800000, 0x00000000ae800200, 0x00000000b3ab0000)
 // 元空间
 Metaspace       used 3652K, capacity 4600K, committed 4864K, reserved 1056768K
  class space    used 410K, capacity 428K, committed 512K, reserved 1048576K

  1.4 jvm常见参数含义

  1.5 调优总结:

    1.将初始的堆大小与最大堆大小相等,来垃圾回收次数从而提高效率。
    2.将新生代或老年代的比例设置为1/3 或者 1/4,让GC尽量去新生代去回收。
         -Xms2000m -Xmx2000m -XX:+PrintGCDetails -XX:+UseSerialGC -XX:NewRatio=4

    此时重新运行java类, 可以对比jvm信息

     

  1.6 Tomcat修改JVM参数:  linux系统修改tomcat/bin/catalina.sh文件,win系统修改tomcat/bin/catalina.bat文件。

    JAVA_OPTS="-server -Xms800m -Xmx800m -XX:PermSize=256m -XX:MaxPermSize=512m -XX:MaxNewSize=512m"

====================================================================

什么是内存泄漏及如何避免

    内存泄漏即:对象可达但不可用,一个对象不再需要使用本该回收时,另一个正在使用的对象却持有它的引用,导致无法回收停留在堆内中。

     防止内存泄露:

      1.尽早释放无用对象的引用, 将不需要使用的对象设置为null,暗示垃圾收集器来收集该对象,防止发生内存泄漏。

      2.程序进行字符串处理时,尽量避免使用String,而应该使用StringBuffer。

        3.尽量少用静态变量

      4.尽量运用对象池技术以提高系统性能

Jvm常见异常处理方案

  内存泄漏: java.lang.OutOfMemory Error:Java heap space

    解决思路:  1. 先查看是不是内存泄漏,如果是通过GC Root的路径来排查

            2. 查看堆内存是否有对象没释放。

            3. 加大物理内存 –Xms, -Xmx,最好-Xms = -Xmx,减少内存扩展的开销。

控制参数:  -Xms (starting 堆的起始大小)         -Xmx (max 堆的最大大小)         -Xmn (new 堆的新生代大小)

  内存溢出: java.OutOfMemory Error:PermGen space

解决思路:  增加参数:-XX:PrintGCDetails,-XX:+PrintGCTimeStamps和-XX:+PrintGCDateStamps 

  线程请求的栈深度大于虚拟机所允许的最大深度java.lang.StackOverflow Error

    解决思路: 可以将栈的深度,理解为数组的长度。

    控制参数:  1. 加大-Xss(每个线程的堆栈大小)参数。

           2. 更换64位虚拟机。

           3. 减少线程。

           4. 减少最大堆(Xmx)。

         java.lang.OutOfMemory Error,有allocate、Native字样

    解决思路:  加大本地内存-MaxDirectMemorySize如不指定则与-Xmx一致。

    以centos6.8 ,100G的内存,参考配置如下:

      JAVA_OPTS="-Xms8g -Xmx8g

            -XX:ParallelGCThreads=8

            -XX:PermSize=2g

            -XX:MaxPermSize=4g

            -Xss512k -Xmn6g

            -XX:-DisableExplicitGC

            -XX:+UseCompressedOops

            -XX:+UseConcMarkSweepGC

            -XX:+CMSParallelRemarkEnabled"

   CATALINA_OPTS="-Xms8g -Xmx8g

            -XX:ParallelGCThreads=8

            -XX:PermSize=2g

            -XX:MaxPermSize=4g

            -Xss512k -Xmn6g

            -XX:-DisableExplicitGC

            -XX:+UseCompressedOops

            -XX:+UseConcMarkSweepGC

            -XX:+CMSParallelRemarkEnabled"

原文地址:https://www.cnblogs.com/wlwl/p/9941196.html

时间: 2024-08-20 11:20:19

四:JVM调优与常见异常处理方案的相关文章

JVM调优总结(四)-分代垃圾回收详述

为什么要分代 分代的垃圾回收策略,是基于这样一个事实:不同的对象的生命周期是不一样的.因此,不同生命周期的对象可以采取不同的收集方式,以便提高回收效率. 在Java程序运行的过程中,会产生大量的对象,其中有些对象是与业务信息相关,比如Http请求中的Session对象.线程.Socket连接,这类对象跟业务直接挂钩,因此生命周期比较长.但是还有一些对象,主要是程序运行过程中生成的临时变量,这些对象生命周期会比较短,比如:String对象,由于其不变类的特性,系统会产生大量的这些对象,有些对象甚至

JVM调优总结 -Xms -Xmx -Xmn -Xss

http://unixboy.iteye.com/blog/174173/ 堆大小设置JVM 中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-bit)限制:系统的可用虚拟内存限制:系统的可用物理内存限制.32位系统下,一般限制在1.5G~2G:64为操作系统对内存无限制.我在Windows Server 2003 系统,3.5G物理内存,JDK5.0下测试,最大可设置为1478m.典型设置: java -Xmx3550m -Xms3550m -Xmn2g -Xss128k-

JVM调优总结

一.相关概念 基本回收算法 引用计数(Reference Counting) 比较古老的回收算法.原理是此对象有一个引用,即增加一个计数,删除一个引用则减少一个计数.垃圾回收时,只用收集计数为0的对象.此算法最致命的是无法处理循环引用的问题. 标记-清除(Mark-Sweep) 此算法执行分两阶段.第一阶段从引用根节点开始标记所有被引用的对象,第二阶段遍历整个堆,把未标记的对象清除.此算法需要暂停整个应用,同时,会产生内存碎片. 复制(Copying) 此 算法把内存空间划为两个相等的区域,每次

jvm调优小结

不区分tomcat,resion等应用,主要是针对jvm调优 tomcat家目录下catalina.sh  catalina.bat 从http://unixboy.iteye.com/blog/174173 http://my.oschina.net/shootercn/blog/15393这个更详细 http://www.360doc.com/content/15/0429/15/7853380_466822446.shtml详细讲解-XX:ParallelGCThreads 学到了很多东西

JVM调优总结 -Xms -Xmx -Xmn -Xss(转载)

堆大小设置JVM 中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-bit)限制:系统的可用虚拟内存限制:系统的可用物理内存限制.32位系统下,一般限制在1.5G~2G:64为操作系统对内存无限制.我在Windows Server 2003 系统,3.5G物理内存,JDK5.0下测试,最大可设置为1478m.典型设置: java -Xmx3550m -Xms3550m -Xmn2g -Xss128k-Xmx3550m:设置JVM最大可用内存为3550M.-Xms3550m:设

转: jvm调优参数总结

JVM里的GC(Garbage Collection)的算法有很多种,如标记清除收集器,压缩收集器,分代收集器等等,详见HotSpot VM GC 的种类 现在比较常用的是分代收集(generational collection,也是SUN VM使用的,J2SE1.2之后引入),即将内存分为几个区域,将不同生命周期的对象放在不同区域里:young generation,tenured generation和permanet generation.绝大部分的objec被分配在young gener

JVM调优参数

堆大小设置JVM 中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-bit)限制:系统的可用虚拟内存限制:系统的可用物理内存限制.32位系统下,一般限制在1.5G~2G:64为操作系统对内存无限制.我在Windows Server 2003 系统,3.5G物理内存,JDK5.0下测试,最大可设置为1478m.典型设置: java -Xmx3550m -Xms3550m -Xmn2g -Xss128k-Xmx3550m:设置JVM最大可用内存为3550M.-Xms3550m:设

JVM调优总结 -Xms -Xmx -Xmn -Xss(转)

堆大小设置JVM 中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-bit)限制:系统的可用虚拟内存限制:系统的可用物理内存限制.32位系统下,一般限制在1.5G~2G:64为操作系统对内存无限制.我在Windows Server 2003 系统,3.5G物理内存,JDK5.0下测试,最大可设置为1478m.典型设置: java -Xmx3550m -Xms3550m -Xmn2g -Xss128k-Xmx3550m:设置JVM最大可用内存为3550M.-Xms3550m:设

JVM调优总结 -Xms

转载自:http://unixboy.iteye.com/blog/174173/ 堆大小设置JVM 中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-bit)限制:系统的可用虚拟内存限制:系统的可用物理内存限制.32位系统下,一般限制在1.5G~2G:64为操作系统对内存无限制.我在Windows Server 2003 系统,3.5G物理内存,JDK5.0下测试,最大可设置为1478m.典型设置: java -Xmx3550m -Xms3550m -Xmn2g -Xss1