精华内容
下载资源
问答
  • JVM参数类型与设置 安装JDK,配置系统环境参数后,输入java -help,红框标记的就是我们设置 JVM参数的区域。 [-options]意思是不强制要求设置,java命令支持各种参数设置,这些参数可以分为以下类别 标准参数:JVM...

    JVM参数类型与设置

    安装JDK,配置系统环境参数后,输入java -help,红框标记的就是我们设置 JVM参数的区域。
    在这里插入图片描述
    [-options]意思是不强制要求设置,java命令支持各种参数设置,这些参数可以分为以下类别

    • 标准参数:JVM的所有实现所支持的最常用的参数 (在jdk各版本之间稳定,不会有较大变化)。
    • 非标准参数(-X):是特定于Java HotSpot虚拟机的通用选项(了解就行)。
    • 高级运行时参数(-XX):控制Java HotSpot VM的运行时行为(重点)。

    这里我们重点讲高级运行时参数,JVM参数主要有boolean值类型与key-value值类型。我们写两个case应用一下,Test是我们的资源类。用boolean值设置打印出GC的详情,用key-value值设置MetaspaceSize内存大小。

    • +表示boolean值true,-表示boolean值false。
    public class Test {
        public static void main(String[] args) throws Exception {
            System.out.println("hello world");
        }
    }
    

    在这里插入图片描述

    • -XX:属性(key)=属性值(value)
      在这里插入图片描述

    JVM参数查看

    查看运行时JVM参数配置信息
    //我们把资源类Test添加sleep用于测试
    public class Test extends ClassLoader {
        public static void main(String[] args) throws Exception {
            System.out.println("hello world");
            Thread.sleep(Integer.MAX_VALUE);
        }
    }
    

    在这里插入图片描述
    此时Test进程阻塞中,我们看看我们的设置的元空间大小是否成功,重新打开一个窗口
    在这里插入图片描述

    • jps:相当于linux的ps -ef|grep java,主要查询出JVM进程的进程编号
    • jinfo:根据JVM进程编号查看该进程的信息
    查看出厂的JVM的参数默认配置信息
    • -XX:+PrintFlagsInitial:查看默认值
      在这里插入图片描述
    • -XX:+PrintFlagsFinal:查看最终值,就是JVM运行时的值
      在这里插入图片描述
      其中带 : 的就是修改过的值,就是JVM修改或者人为的修改过的值。
    • -XX:+PrintCommandLineFlags:查看当前常用参数默认值
      在这里插入图片描述

    JVM常用参数

    • -Xms(最小堆内存)、-Xmx(最大堆内存)
      在这里插入图片描述
    public class Test {
    
        public static void main(String[] args) throws Exception {
            long totalMemory = Runtime.getRuntime().totalMemory();
            long maxMemory = Runtime.getRuntime().maxMemory();
            System.out.println("totalMemory(-Xms) = " + totalMemory / (double) 1024 / 1024 + "MB");
            System.out.println("maxMemory(-Xmx) = " + maxMemory / (double) 1024 / 1024 + "MB");
        }
    }
    

    我的电脑内存为8G,JVM初始内存一般为物理内存的1/64,最大内存为物理内存的1/4。(拓展:-Xms=-XX:InitialHeapSize,-Xmx=-XX:MaxHeapSize)

    totalMemory(-Xms) = 123.0MB
    maxMemory(-Xmx) = 1803.0MB
    
    • -Xss(单个线程栈的内存大小)
      一般默认值为512KB~1024KB,我们可以按上面的查看方式确认一下默认值
      在这里插入图片描述
      发现竟然是0,怎么可能,我们去官网看看为什么,发现0表示使用的是默认值,这个默认值又依赖于平台,不同平台就不一样。
      在这里插入图片描述(拓展:-Xss=-XX:ThreadStackSize)
    • -Xmn(新生代内存大小)
      一般不去设置,默认新生代大小堆内存的1/3,老年代堆内存的2/3
    • -XX:MetaspaceSize
      在再JDK1.8后,永久代被元空间所取代,它们之间最大的区别是永久代使用的内存是JVM的堆内存,而元空间使用的是本地内存。本地内存(Native memory),也称为C-Heap,是供JVM自身进程使用的。当Java Heap空间不足时会触发GC,但Native memory空间不够却不会触发GC。默认情况下元空间的大小只受本地物理内存限制。初始默认大小为21M左右。
    • -XX:+PrintGCDetails
      打印垃圾回收信息,设置一个需要GC的场景
    public class Test {
    
        public static void main(String[] args) throws Exception {
            System.out.println("hello world");
            //创建一个大对象
            byte[] bytes = new byte[1024 * 1024 * 50];
        }
    }
    

    执行时设置最大堆内存小于50m,即可出现GC的动作。
    在这里插入图片描述
    结合上图的GC信息,分析当前堆内存使用情况
    在这里插入图片描述

    • -XX:SurvivorRatio
      作用是设置新生代的Eden区与Survivor-From和Survivor-To的比例,默认为8,就是8:1:1,如果修改为2,则2:1:1,Survivor-From和Survivor-To是相同的。
      新生代
      使用-XX:PrintGCDetails,查看发现eden为33280K,from为5120K,to为5120K
      在这里插入图片描述

    • -XX:NewRatio
      设置新生代老年代的比例,默认为2,就是新生代1/3,老年代2/3。如果修改5,则新生代为1/6,老年代就是5/6。

    • -XX:MaxTenuringThreshold
      设置用于自适应GC大小调整的最大使用期限阈值。最大值为15。并行(吞吐量)收集器的默认值为15,而CMS收集器的默认值为6。理解它之前我们先了解一下MinorGC执行的流程。
      1)首先当Eden区满时,第一次GC,把还活着的对象拷贝到Survivor-From区,
      2)当Eden区再次出发GC的时候,会扫描Eden区和Survivor-From区,对这俩区进行垃圾回收。
      3)经过垃圾回收后,还存活的对象直接复制到Survivor-To区,同时把复制到Survivor-To区的对象年龄+1。
      4)然后清空Eden和Survivor-From区,
      5)最后将Survivor-From区改为Survivor-To区,Survivor-To区改为Survivor-From区,谁空谁就是Survivor-To区。
      MinorGC执行时,部分对象在Survivor-From和Survivor-To区复制来复制区,来回交换15次最终还是存活则存入到老年代。改参数就是新生代对象转为老年代对象的难易程度,最大GC后存活15次即可移入老年代。

    JVM常见异常

    java.lang.StackOverflowError

    原因:线程请求的栈深度 超过了虚拟机允许的深度

    public class Test {
    	//代码例子
        public static void main(String[] args) throws Exception {
            stackOverflowError();
        }
        private static void stackOverflowError(){
            stackOverflowError();
        }
    }
    

    线程栈帧结构图:
    在这里插入图片描述

    java.lang.OutOfMemoryError:Java heap space

    原因:表示的是新对象不能在java heap中分配。

    public class Test {
      	//代码例子 启动参数添加 -Xms20m -Xmx20m
        public static void main(String[] args) throws Exception {
            byte[] bytes = new byte[1024 * 1024 * 50];
        }
    }
    
    java.lang.OutOfMemoryError:GC overhead limit exceeded

    原因:GC回收时间过长时会抛出OutOfMemoryError,过长的定义是超过98%的时间在GC并且回收不到2%的堆内存。如果不抛出GC overhead limit,将会频繁GC,造成恶性循环,造成CPU高使用率。

    public class Test {
        //代码例子 启动参数添加 -Xms10m -Xmx10m -XX:MaxDirectMemorySize=5m -XX:+PrintGCDetails
        public static void main(String[] args) throws Exception {
            int i = 0;
            List<String> list = new ArrayList<>();
    
            try {
                while (true) {
                    list.add(String.valueOf(++i).intern());
                }
            } catch (Throwable t) {
                System.out.println("i = " + i);
                t.printStackTrace();
                throw t;
            }
        }
    }
    

    GC详情,可以看出GC效果差,GC前后内存变化小

    [Full GC (Ergonomics) [PSYoungGen: 2047K->2047K(2560K)] [ParOldGen: 7048K->7048K(7168K)] 9096K->9096K(9728K), [Metaspace: 2841K->2841K(1056768K)], 0.0388129 secs] [Times: user=0.25 sys=0.00, real=0.04 secs] 
    
    java.lang.OutOfMemoryError:Direct buffer Memory

    NIO:1.8的新特性,NIO三大组件Selector、Channel、Buffer。它可以通过Native函数库直接分配堆外内存,然后通过在JVM堆中的DirectByteBuffer对象作为这块内存的引用进行操作,这样可以在某些场景中显著提高性能,因为避免了数据在Java堆和Native堆来回复制。

    原因:NIO代码造成操作系统本地内存不足。

    public class Test {
        //查看最大的本地直接内存,默认为物理内存1/4
        public static void main(String[] args) throws Exception {
            System.out.println("maxDirectMemory = " + (sun.misc.VM.maxDirectMemory()/(double)1024/1024+"MB"));
        }
    }
    
    public class Test {
        //代码例子 启动参数添加 -Xms10m -Xmx10m -XX:MaxDirectMemorySize=5m
        public static void main(String[] args) throws Exception {
            //在Java堆中分配内存,属于GC管辖范围,由于需要拷贝,速度相对较慢
    //       ByteBuffer.allocate(1);
            //在本地内存中分配内存,不属于GC管辖范围,不需要拷贝,速度相对较快
            ByteBuffer.allocateDirect(1024 * 1024 * 10);
        }
    }
    
    java.lang.OutOfMemoryError:unable to create new native thread

    原因:程序创建的线程太多,超过了平台系统的极限(Linux系统单个进程默认可以创建的线程最大数为1024个)

    public class Test {
        //代码例子 请在Linux上执行
        public static void main(String[] args) throws Exception {
            for (int i = 0; ; i++) {
                System.out.println("i = " + i);
                new Thread(() -> {
                    try {
                        Thread.sleep(Integer.MAX_VALUE);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }).start();
            }
        }
    }
    
    ulimit -u #查看当前用户的最大线程数
    vim /etc/security/limits.d/90-nproc.conf #修改创建线程上线
    
    java.lang.OutOfMemoryError:Metaspace

    1.8的新特性:Metaspace代替了永久代,是方法区在HotSpot中的实现,并不占用虚拟机内存,而是使用本地内存,也可以称它为native memory。主要存放:虚拟机加载的类信息、常量、静态变量、即时编译后的代码。

    原因:Metaspace内存不足

    public class Test {
        //资源类
        static class Obj {
        }
    
        //代码例子 启动参数添加-XX:MetaspaceSize=10m -XX:MaxMetaspaceSize=10m
        public static void main(String[] args) throws Exception {
            int i = 0;
            try {
                while (true) {
                    i++;
                    Enhancer enhancer = new Enhancer();
                    enhancer.setSuperclass(Obj.class);
                    enhancer.setUseCache(false);
                    enhancer.setCallback(new MethodInterceptor() {
                        @Override
                        public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
                            return proxy.invoke(obj, args);
                        }
                    });
                    enhancer.create();
                }
            } catch (Throwable t) {
                System.out.println("i = " + i);
                t.printStackTrace();
            }
        }
    }
    

    记得引包

    <!-- https://mvnrepository.com/artifact/cglib/cglib -->
    <dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib</artifactId>
        <version>3.3.0</version>
    </dependency>
    
    
    展开全文
  • - 了解下我们为什么要学习JVM优化 - 掌握jvm的运行参数以及参数的设置 - 掌握jvm的内存模型(堆内存) - 掌握jamp命令的使用以及通过MAT工具进行分析 - 掌握定位分析内存溢出的方法 - 掌握jstack命令的使用 - 掌握...
  • JVM中是+XX配置实现的搭配组合: UseSerialGC 表示 “Serial” + "Serial Old"组合 UseParNewGC 表示 “ParNew” + “Serial Old” UseConcMarkSweepGC 表示 “ParNew” + “CMS”. 组合,“CMS” 是针对旧生代...
  • jvm优化

    2011-03-29 10:10:00
    jvm优化配置 文章分类:Java编程 JVM优化配置《一》 OOM这个缩写就是Java程序开发过程中让人最头痛的问题:Out of Memory。在很多开发人员的开发过程中,或多或少的都会遇到这类问题,这类问题定位比较困难,...

    jvm优化配置

    文章分类:Java编程

    JVM优化配置《一》

    OOM这个缩写就是Java程序开发过程中让人最头痛的问题:Out of Memory。在很多开发人员的开发过程中,或多或少的都会遇到这类问题,这类问题定位比较困难,往往需要根据经验来判断可能出现问题的代码。原因主要是 两个:对象没有被释放(多种情况引起,往往是比较隐蔽的引用导致被Hold而无法被回收)。另一种就是真的Memory不够用了,需要增加JVM的 Heap来满足应用程序的需求。最近有同事发的关于解决OOM的问题,让我了解了原来OOM除了在JVM Heap不够时会发生,在Native Heap不够的时候也会发生,同时JVM Heap和Native Heap存在着相互影响和平衡的关系,因此就仔细的去看了关于OOM和JVM配置优化的内容。
    OOM
           在 其他语言类似于C,Delphi等等由于内存都是由自己分配和管理,因此内存泄露的问题比较常见,同时也是很头痛的一件事情。而Java的对象生命周期管 理都是JVM来做的,简化了开发人员的非业务逻辑的处理,但是这种自动管理回收机制也是基于一些规则的,而违背了这些规则的时候,就会造成所谓的 “Memory Leak”。
    OOM(Java Heap)
           错误提示:java.lang.OutOfMemoryError。
    这 类OOM是由于JVM分配的给应用的Heap Memory已经被耗尽,可能是因为应用在高负荷的情况下的却需要很大的内存,因此可以通过修改JVM参数来增加Java Heap Memory(不过也不能无限制增加,后面那种OOM有可能就是因为这个原因而产生)。另一种情况是因为应用程序使用对象或者资源没有释放,导致内存消耗 持续增加,最后出现OOM,这类问题引起的原因往往是应用已不需要的对象还被其他有效对象所引用,那么就无法释放,可能是业务代码逻辑造成的(异常处理不 够例如IO等资源),也可能是对于第三方开源项目中资源释放了解不够导致使用以后资源没有释放(例如JDBC的ResultSet等)。
           几个容易出现问题的场景:
           1.应用的缓存或者Collection:如果应用要缓存Java对象或者是在一个 Collection中保存对象,那么就要确定是否会有大量的对象存入,要做保护,以防止在大数据量下大量内存被消耗,同时要保证Cache的大小不会无限制增加。
           2.生命周期较长的对象:尽量简短对象的生命周期,现在采用对象的创建释放代价已经很低,同时作了很好的优化,要比创建一个对象长期反复使用要好。如果能够设置超时的情景下,尽量设置超时。
           3.类似于JDBC的Connection Pool,在使用Pool中的对象以后需要释放并返回,不然就会造成Pool的不断增大,在其他Pool中使用也是一样。同样ResultSet,IO这类资源的释放都需要注意。
           解决的方法就是查找错误或者是增加Java Heap Memory。对于此类问题检测工具相当多,这里就不做介绍了。     
    OOM(Native Heap)
    错误提示:requested XXXX bytes for ChunkPool::allocate. Out of swap space。
           Native Heap Memory是JVM 内部使用的Memory,这部分的Memory可以通过JDK提供的JNI的方式去访问,这部分Memory效率很高,但是管理需要自己去做,如果没有把 握最好不要使用,以防出现内存泄露问题。JVM 使用Native Heap Memory用来优化代码载入(JTI代码生成),临时对象空间申请,以及JVM内部的一些操作。这次同事在压力测试中遇到的问题就是这类OOM,也就是 这类Memory耗尽。同样这类OOM产生的问题也是分成正常使用耗尽和无释放资源耗尽两类。无释放资源耗尽很多时候不是程序员自身的原因,可能是引用的 第三方包的缺陷,例如很多人遇到的Oracle 9 JDBC驱动在低版本中有内存泄露的问题。要确定这类问题,就需要去观察Native Heap Memory的增长和使用情况,在服务器应用起来以后,运行一段时间后JVM对于Native Heap Memory的使用会达到一个稳定的阶段,此时可以看看什么操作对于Native Heap Memory操作频繁,而且使得Native Heap Memory增长,对于Native Heap Memory的情况我还没有找到办法去检测,现在能够看到的就是为JVM启动时候增加-verbose:jni参数来观察对于Native Heap Memory的操作。另一种情况就是正常消耗Native Heap Memory,对于Native Heap Memory的使用主要取决于JVM代码生成,线程创建,用于优化的临时代码和对象产生。当正常耗尽Native Heap Memory时,那么就需要增加Native Heap Memory,此时就会和我们前面提到增加java Heap Memory的情况出现矛盾。
    应用内存组合
           对 于应用来说,可分配的内存受到OS的限制,不同的OS对进程所能访问虚拟内存地址区间直接影响对于应用内存的分配,32位的操作系统通常最大支持4G的内 存寻址,而Linux一般为3G,Windows为2G。然而这些大小的内存并不会全部给JVM的Java Heap使用,它主要会分成三部分:Java Heap,Native Heap,载入资源和类库等所占用的内存。那么由此可见,Native Heap和 Java Heap大小配置是相互制约的,哪一部分分配多了都可能会影响到另外一部分的正常工作,因此如果通过命令行去配置,那么需要确切的了解应用使用情况,否则 采用默认配置自动监测会更好的优化应用使用情况。
           同样要注意的就是进程的虚拟内存和机器的实际内存还是有区别的,对于机器来说实际内存以及硬盘提供的虚拟内存都是提供给机器上所有进程使用的,因此在设置JVM参数时,它的虚拟内存绝对不应该超过实际内存的大小。
    《二》
           这 里首先要说明的是这里提到的JVM是Sun的HotSpot JVM 5和以上的版本。性能优化在应用方面可以有很多手段,包括Cache,多线程,各种算法等等。通常情况下是不建议在没有任何统计和分析的情况下去手动配置 JVM的参数来调整性能,因为在JVM 5以上已经作了根据机器和OS的情况自动配置合适参数的算法,基本能够满足大部分的情况,当然这种自动适配只是一种通用的方式,如果说真的要达到最优,那 么还是需要根据实际的使用情况来手动的配置各种参数设置,提高性能。
           JVM能够对性能产生影响的最大部分就是对于内存的管理。从jdk 1.5以后内存管理和分配有了很多的改善和提高。
    内存分配以及管理的几个基本概念和参数说明:
    Java Hotspot Mode:
    server 和 client两种模式,如果不配置,JVM会根据应用服务器硬件配置自动选择模式,server模式启动比较慢,但是运行期速度得到了优化,client 启动比较快,但是运行期响应没有server模式的优化,适合于个人PC的服务开发和测试。
    Garbage Collector Policy:
           在Jdk 1.5的时候已经提供了三种GC,除了原来提供的串行GC(SerialGC)以外,还提供了两种新的GC:ParallelGC和 ConcMarkSweepGC。ParallelGC采用了多线程并行管理和回收垃圾对象,提高了回收效率,提高了服务器的吞吐量,适合于多处理器的服 务器。ConcMarkSweepGC采用的是并发方式来管理和回收垃圾对象,降低垃圾回收产生的响应暂停时间。这里说一下并发和并行的区别,并发指的是 多个进程并行执行垃圾回收,那么可以很好的利用多处理器,而并行指的是应用程序不需要暂停可以和垃圾回收线程并发工作。串行GC适合小型应用和单处理器系 统(无需多线程交互,效率比较高),后两者适合大型系统。
           使用方式就是在参数配置中增加-XX:+UseParallelGC等方式来设置。
           对于这部分的配置在网上有很多的实例可以参考,不过最终采用哪一种GC还是要根据具体的情况来分析和选择。
    Heap:
           OOM的 各种经历已经让每一个架构师开发人员看到了了解Heap的重要性。OOM已经是Heap的临界点,不得不引起注意,然而Heap对于性能的潜在影响并未被 引起重视,不过和GC配置一样,在没有对使用情况作仔细分析和研究的情况下,贸然的去修改Heap配置,可能适得其反,这里就来看一下Heap的一些概念 和对于性能的影响。
           我们的应用所能够得到的最大的Heap受三部分因素的制约:数据处理 模型(32位或者64位操作系统),系统地虚拟内存总数和系统的物理内存总数。首先Heap的大小不能超过不同操作系统的进程寻址范围,当前大部分系统最 高限度是4G,Windows通常是2G,Linux通常是3G。系统的虚拟内存也是分配的依据,首先是不能超过,然后由于操作系统支持硬盘来做部分的虚 拟内存,如果设置过大,那么对于应用响应来说势必有影响。再则就是要考虑同一台服务器上运行多个Java虚拟机所消耗的资源总合也不能超过可用资源。就和 前面OOM分析中的一样,其实由于OS的数据处理模型的限制,机器本身的硬件内存资源和虚拟内存资源并不一定会匹配,那么在有限的资源下如何调整好资源分 配,对于应用来说尤为重要。
    关于Heap的几个参数设置:
           说了Heap的有限资源问题以后,就来看看如何通过配置去改变JVM对于Heap的分配。下面所说的主要是对于Java Heap的分配,那么在申请了Java Heap以后,剩下的可用资源就会被使用到Native Heap。
           Xms: java heap初始化时的大小。默认情况是机器物理内存的1/64。这个主要是根据应用启动时消耗的资源决定,分配少了申请起来会降低启动速度,分配多了也浪费。
           Xmx:java heap的 最大值,默认是机器物理内存的1/4,最大也就到1G。这个值决定了最多可用的Java Heap Memory,分配过少就会在应用需要大量内存作缓存或者零时对象时出现OOM的问题,如果分配过大,那么就会产生上文提到的第二类OOM。所以如何配置 还是根据运行过程中的分析和计算来确定,如果不能确定还是采用默认的配置。
           Xmn:java heap新 生代的空间大小。在GC模型中,根据对象的生命周期的长短,产生了内存分代的设计:青年代(内部也分成三部分,类似于整体划分的作用,可以通过配置来设置 比例),老年代,持久代。每一代的管理和回收策略都不相同,最为活跃的就是青年代,同时这部分的内存分配和管理效率也是最高。通常情况下,对于内存的申请 优先在新生代中申请,当内存不够时会整理新生代,当整理以后还是不能满足申请的内存,就会向老年代移动一些生命周期较长的对象。这种整理和移动会消耗资 源,同时降低系统运行响应能力,因此如果青年代设置的过小,就会频繁的整理和移动,对性能造成影响。那是否把年青代设置的越大越好,其实不然,年青代采用 的是复制搜集算法,这种算法必须停止所有应用程序线程,服务器线程切换时间就会成为应用响应的瓶颈(当然永远不用收集那么就不存在这个问题)。老年代采用 的是串行标记收集的方式,并发收集可以减少对于应用的影响。
           Xss:线程堆栈最大值。允许更多的虚拟内存空间地址被Java Heap使用。
    以下是sun公司的性能优化白皮书中提到的几个例子:
    1.对于吞吐量的调优。机器配置:4G的内存,32个线程并发能力。
    java -Xmx3800m -Xms3800m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20
           -Xmx3800m -Xms3800m 配置了最大Java Heap来充分利用系统内存。
           -Xmn2g 创建足够大的青年代(可以并行被回收)充分利用系统内存,防止将短期对象复制到老年代。
        -Xss128 减少默认最大的线程栈大小,提供更多的处理虚拟内存地址空间被进程使用。
        -XX:+UseParallelGC 采用并行垃圾收集器对年青代的内存进行收集,提高效率。
        -XX:ParallelGCThreads=20 减少垃圾收集线程,默认是和服务器可支持的线程最大并发数相同,往往不需要配置到最大值。
    2.尝试采用对老年代并行收集
    java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20 -XX:+UseParallelOldGC
    -Xmx3550m -Xms3550m 内存分配被减小,因为ParallelOldGC会增加对于Native Heap的需求,因此需要减小Java Heap来满足需求。
    -XX:+UseParallelOldGC 采用对于老年代并发收集的策略,可以提高收集效率。
    3.提高吞吐量,减少应用停顿时间
    java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:ParallelGCThreads=20 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:SurvivorRatio=8 -XX:TargetSurvivorRatio=90 -XX:MaxTenuringThreshold=31
    -XX:+UseConcMarkSweepGC -XX:+UseParNewGC 选择了并发标记交换收集器,它可以并发执行收集操作,降低应用停止时间,同时它也是并行处理模式,可以有效地利用多处理器的系统的多进程处理。
    -XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=31 表示在青年代中Eden和Survivor比例,设置增加了Survivor的大小,越大的survivor空间可以允许短期对象尽量在年青代消亡。
    -XX:TargetSurvivorRatio=90 允许90%的空间被占用,超过默认的50%,提高对于survivor的使用率。
    类似的例子网上很多,这儿就不在列下来了,最终是否采取自己配置来替换默认配置还是要根据虚拟机的使用情况来分析和配置。

    转自:http://blog.csdn.net/cenwenchu79/archive/2008/01/22/2059553.aspx
    展开全文
  • 【JVM虚拟机】JVM优化

    2020-04-07 20:48:02
    文章目录JVM优化原则:GC优化的目的:一般步骤为:1、监控GC的状态2、分析结果,判断是否需要优化3、调整GC类型和内存分配4、不断的分析的调整5、全面应用参数常见问题定位过程(频繁GC问题或内存溢出问题)死锁问题...

    JVM优化

    对参数设置,java命令的学习,都是为了JVM调优,在调优之前,我们需要记住下面的

    原则:

    1、多数的java应用不需要在服务器上进行GC优化;
    2 、多数导致GC问题的java应用,都不是因为我们参数设置错误,而是代码问题;
    3、在应用上线之前,先考虑将机器的JVM参数到最优(最适合);
    4、减少创建对象的数量;
    5、减少使用全局变量和大对象;
    6、GC优化是到最后不得已才采用的手段
    7、在实际使用中,分析GC情况优化代码比优化GC参数要多得多;

    GC优化的目的:

    将转移到老年代的对象数量降低到最低
    减少 full GC 的执行时间

    真正熟练的使用GC调优,是建立在多次进行GC监控和调优的实战经验上的,进行监控和调优的

    一般步骤为:

    1、监控GC的状态

    使用各种JVM工具,查看当前日志,分析当前JVM参数设置,并且分析当前堆内存快照和ge日志,根据实际的各区域内存划分和GC执行时间,觉得是否进行优化;

    2、分析结果,判断是否需要优化

    如果各项参数设置合理,系统没有超时日志出现,GC效率不高,GC耗时不高,那么没有必要进行GC优化;如果GC时间超过1-3秒,或者频繁GC,则必须优化;
    注;如果满足下面的指标,则一般不需要进行GC:
    Minor GC执行时间不到50ms;
    Minor GC执行不频繁,约10秒一次;
    Full GC执行时间不到1s;
    Full GC执行频率不算频繁,不低于10分钟1次;

    3、调整GC类型和内存分配

    如果内存分配过大或过小,或者采用的GC收集器比较慢,则应该优先调整这些参数,并且先找1台或几台机器进行beta,然后比较优化过的机器和没有优化的机器的性能对比,并有针对性的做出最后选择;

    4、不断的分析的调整

    通过不断的试验和试错,分析并找到最合适的参数;

    5、全面应用参数

    如果找到了最合适的参数,则将这些参数应用到所有服务器,并进行后续跟踪。

    常见问题定位过程(频繁GC问题或内存溢出问题)

    一、使用jps查看线程ID
    二、使用jstat -gc 3331 250 20 查看gc情况,一般比较关注PERM区的情况,查看GC的增长情况。
    三、使用jstat -gccause:额外输出上次GC的原因
    四、使用jmap -dump:format=b,file=heapDump 3331 生成堆转储文件
    五、使用jhat或者可视化工具(Eclipse Memory Analyer、IBM HeapAnalyzer)分析堆情况
    六、结合代码解决内存溢出或泄露问题

    死锁问题

    一、使用jps查看线程ID
    二、使用jstack 3331:查看线程情况

    1、首先需要确定java进程是否发生死锁
    2、打开jvisualvm 工具,专门分析JVM CPU ,内存使用情况,以及线程的进行信息查看当前java进程各个线程运行的状态(颜色)
    3、通过jvisualvm 的线程dump或者jstack命令,把当前java进程所有线程的调用堆栈信息打印出来
    4、分析main线程和子线程有没有关键短语:
    waiting for(资源地址)
    waiting to lock(资源地址)
    5、看线程函数调用栈,定位到源码上,具体问题具体分析

    展开全文
  • 本章讲解JVM优化常见的工具的使用 方法 1.概念 在JVM优化的道路上,任重道远,我们需要借助JDK本身的工具进行分析。 2.工具详情 下面介绍的小工具均在JAVA_HOME/bin下,我的路径是这样的。 1)jps:JVM ...

    前言

          本章讲解JVM优化中常见的工具的使用

    方法

    1.概念

    在JVM优化的道路上,任重道远,我们需要借助JDK本身的工具进行分析。

    2.工具详情

    下面介绍的小工具均在JAVA_HOME/bin下,我的路径是这样的。

    1)jps:JVM Process Status Tool,显示系统内所有的JVM进程

    语法:

    • -q
      只输出LVMID,省略主类名称;

    • -m
      输出虚拟机进程启动时传给主类函数的参数;

    • -l
      输出主类的完成package名称或者jar包完整路径名;

    • -v
      输出虚拟机启动时的JVM参数

    使用示例:

    2)jstat:JVM Statistics Monitoring Tool,可以收集JVM相关的运行数据

    语法:

    jstat命令稍许有些复杂,它主要有以下参数:

    1. option:选项,jstat主要提供以下选项:

      • -class
        监视类的装载/卸载数量、总空间以及类装载所耗时间;

      • -gc
        监视java heap情况,包括eden区和两个survivor区、old区、永久区等的容量,已用空间和GC时间等信息;

      • -gccapacity
        监视内容与-gc基本是一致的,-gccapacity的输出包括heap各个区域使用到的最大最小空间;

      • gcutil
        监视内容同样与-gc基本一致,-gcutil的输出主要是heap各个区域使用空间占总空间百分比;

      • gccause
        -gcutil功能一致,但是会额外输出导致上一次gc的原因;

      • gcnew
        监视young区gc情况;

      • gcnewcapacity
        监视内容与-gcnew基本相同,-gcnewcapacity的输出包括使用到的最大最小空间;

      • -gcold
        监视old区gc情况;

      • -gcoldcapacity
        监视内容与-gcold基本相同,-gcoldcapacity的输出包括使用到的最大最小空间;

      • -gcpermcapacity
        输出永久代使用到的最大最小空间。注意:JDK 8废除了永久代,引入了Metaspace,这个命令在JDK 8的环境下就不能使用了,那要看元数据空间相关情况,使用-gcmetacapacity即可

      • -compiler
        输出JIT编译器编译过的方法以及耗时等信息;
      • -printcompilation
        输出以及被JIT编译的方法
    2. vmid:虚拟机进程id,这时候小伙伴们肯定又要开始疑惑了,这个vmid与lvmid又有什么区别?其实对于本地虚拟机进程,它俩没任何区别,但是如果是远程虚拟机进程,它俩就有区别了,远程虚拟机进程vmid格式应该是这样:
      [protocol:][//] lvmid [@hostname[:port]/servername]

    3. interval:查询时间间隔;

    4. count:查询次数。

    使用示例:

    其中的内涵大家自行百度。

    其他的还有如下的小工具大家可以自行查找。

    • jinfo:Configuration Info for Java,显示JVM配置信息;

    • jmap:Memory Map for Java,用于生成JVM的内存快照;

    • jhat:JVM Heap Dump Browser,用于分析heapdump文件,它可以建立一个http/html服务,使用者可以在浏览器上查看分析结果;

    • jstack:Stack Trace for Java,显示JVM的线程快照。

    前面的都是虾兵蟹将,接下来出场的才是重头戏,也就是融合了前面所有工具功能的图形化用户界面jvisualvm

    该工具极其强大,是JVM分析的首选!

    附录一:jvisualvm添加GC插件

    jvisualvm还有个功能就是可以添加我们所需要的插件,其中GC插件尤为重要!

    1.工具->插件

    2.选择可用插件->Visual GC

    3.一路下一步

    4.完成后重启应用程序即可看到如下tab页

    展开全文
  • 一、常见JVM参数配置: 1、垃圾回收统计信息: -XX:+PrintGC打印GC简要信息 -XX:+PrintGCDetails打印GC的详细信息 -XX:+PrintGCTimeStamps打印CG发生的时间戳 -Xloggc:log/gc.log指定GC log的位置,以文件...
  • Jboss_JVM优化

    2013-05-30 12:55:54
    Jboss中间件下jvm参数调优配置 Jvm常见调优配置汇总
  • jvm优化 JVM 内存大小设置

    千次阅读 2018-06-22 17:11:27
    Tomcat的内存溢出本质就是JVM内存溢出,所以在本文开始时,应该先对Java JVM有关内存方面的知识进行详细介绍。一、Java JVM内存介绍JVM管理两种类型的内存,堆和非堆。按照官方的说法:“Java 虚拟机具有一个堆,堆...
  • 常见JVM运行时参数
  • JVM优化和垃圾回收机制

    千次阅读 2020-07-19 15:02:21
    JVM优化 Java堆 堆内存用于存放由new创建的对象和数组。在堆中分配的内存,由java虚拟机自动垃圾回收器来管理。在堆中产生了一个数组或者对象后,还可以在栈中定义一个特殊的变量,这个变量的取值等于数组或者对象在...
  • jvm知识对于java开发人员的重要性不言而喻,我们看了各种jvm优化、垃圾回收算法、内存调优的知识点,早就摩拳擦掌想实战了,奈何程序偏偏不溢出了,下面几段代码能帮助你虐爆JVM各个内存区。
  • JVM优化系列-详解JVM堆内存分析

    千次阅读 2019-12-17 14:42:31
      了解过java虚拟机的读者都知道,在JVM的内存可以分为堆内存和非堆内存,在之前的博客中分享了关于JVM常见参数的配置。这次分享的内容主要是对堆和非堆内存参数的配置   在Java程序运行的过程中,如果堆空间...
  • Tomcat8性能JVM优化

    2020-03-31 15:34:58
    JVM性能调优: 常见 catalina.sh 配置汇总 JAVA_OPTS="$JAVA_OPTS -server -Xms1024m -Xmx1024m -Xss256k -XX:+UseParallelOldGC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/heap_dump -XX:+...
  • 美团jvm优化案例

    千次阅读 2018-01-17 10:59:50
    当Java程序性能达不到既定目标,且其他优化手段都已经穷尽时,通常需要调整垃圾回收器来进一步提高性能,称为GC优化。但GC算法复杂,影响GC性能的参数众多,且参数调整又依赖于应用各自...优化前准备: 简单回顾JVM相关

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 80,133
精华内容 32,053
关键字:

常见jvm优化