常见参数配置

-XX:+PrintGC      每次触发GC的时候打印相关日志

-XX:+UseSerialGC      串行回收

-XX:+PrintGCDetails  更详细的GC日志

-Xms               堆初始值

-Xmx               堆最大可用值

-Xmn               新生代堆最大可用值

-XX:SurvivorRatio  用来设置新生代中eden空间和from/to空间的比例.

-XX:NewRatio       配置新生代与老年代占比 1:2

含以-XX:SurvivorRatio=eden/from=den/to

总结:在实际工作中,我们可以直接将初始的堆大小与最大堆大小相等,

这样的好处是可以减少程序运行时垃圾回收次数,从而提高效率。

-XX:SurvivorRatio     用来设置新生代中eden空间和from/to空间的比例.

堆内存大小配置

使用示例:  -Xmx20m -Xms5m

说明: 当下Java应用最大可用内存为20M, 初始内存为5M

// byte[] b = new byte[4 * 1024 * 1024];

// System.out.println("分配了4M空间给数组");

System.out.print("最大内存");

System.out.println(Runtime.getRuntime().maxMemory() / 1024.0 / 1024 + "M");

System.out.print("可用内存");

System.out.println(Runtime.getRuntime().freeMemory() / 1024.0 / 1024 + "M");

System.out.print("已经使用内存");

System.out.println(Runtime.getRuntime().totalMemory() / 1024.0 / 1024 + "M");

设置新生代比例参数

使用示例:-Xms20m -Xmx20m -Xmn1m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC

说明:堆内存初始化值20m,堆内存最大值20m,新生代最大值可用1m,eden空间和from/to空间的比例为2/1

byte[] b = null;

for (int i = 0; i < 10; i++) {

b = new byte[1 * 1024 * 1024];

}

使用示例: -Xms20m -Xmx20m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC设置新生代与老年代比例参数

-XX:NewRatio=2

说明:堆内存初始化值20m,堆内存最大值20m,新生代最大值可用1m,eden空间和from/to空间的比例为2/1

新生代和老年代的占比为1/2

实战OutOfMemoryError异常

Java堆溢出

错误原因: java.lang.OutOfMemoryError: Java heap space 堆内存溢出

解决办法:设置堆内存大小 // -Xms1m -Xmx10m -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError

// -Xms1m -Xmx10m -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError

List<Object> listObject = new ArrayList<>();

for (int i = 0; i < 10; i++) {

System.out.println("i:" + i);

Byte[] bytes = new Byte[1 * 1024 * 1024];

listObject.add(bytes);

}

System.out.println("添加成功...");

虚拟机栈溢出

错误原因: java.lang.StackOverflowError  栈内存溢出

栈溢出 产生于递归调用,循环遍历是不会的,但是循环方法里面产生递归调用, 也会发生栈溢出。

解决办法:设置线程最大调用深度

-Xss5m 设置最大调用深度

publicclass JvmDemo04 {

       privatestaticintcount;

       publicstaticvoid count(){

           try {

                  count++;

                  count();

           } catch (Throwable e) {

                 System.out.println("最大深度:"+count);

                 e.printStackTrace();

           }

       }

       publicstaticvoid main(String[] args) {

            count();

      }

}

内存溢出与内存泄漏区别

Java内存泄漏就是没有及时清理内存垃圾,导致系统无法再给你提供内存资源(内存资源耗尽);

而Java内存溢出就是你要求分配的内存超出了系统能给你的,系统不能满足需求,于是产生溢出。

内存溢出,这个好理解,说明存储空间不够大。就像倒水倒多了,从杯子上面溢出了来了一样。
内存泄漏,原理是,使用过的内存空间没有被及时释放,长时间占用内存,最终导致内存空间不足,而出现内存溢出。

垃圾收集器

串行与并行收集器

串行回收: JDK1.5前的默认算法 缺点是只有一个线程,执行垃圾回收时程序停止的时间比较长

并行回收: 多个线程执行垃圾回收适合于吞吐量的系统,回收时系统会停止运行

serial收集器

串行收集器是最古老,最稳定以及效率高的收集器,可能会产生较长的停顿,只使用一个线程去回收。新生代、老年代使用串行回收;新生代复制算法、老年代标记-压缩;垃圾收集的过程中会Stop The World(服务暂停)

一个单线程的收集器,在进行垃圾收集时候,必须暂停其他所有的工作线程直到它收集结束。

特点:CPU利用率最高,停顿时间即用户等待时间比较长。

适用场景:小型应用

通过JVM参数-XX:+UseSerialGC可以使用串行垃圾回收器。

ParNew收集器

ParNew收集器其实就是Serial收集器的多线程版本。新生代并行,老年代串行;新生代复制算法、老年代标记-压缩

参数控制:-XX:+UseParNewGC  ParNew收集器

-XX:ParallelGCThreads
限制线程数量

parallel 收集器

Parallel
Scavenge收集器类似ParNew收集器,Parallel收集器更关注系统的吞吐量。可以通过参数来打开自适应调节策略,虚拟机会根据当前系统的运行情况收集性能监控信息,动态调整这些参数以提供最合适的停顿时间或最大的吞吐量;也可以通过参数控制GC的时间不大于多少毫秒或者比例;新生代复制算法、老年代标记-压缩

采用多线程来通过扫描并压缩堆
特点:停顿时间短,回收效率高,对吞吐量要求高。
适用场景:大型应用,科学计算,大规模数据采集等。
通过JVM参数
XX:+USeParNewGC 打开并发标记扫描垃圾回收器。

cms收集器

CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器。目前很大一部分的Java应用都集中在互联网站或B/S系统的服务端上,这类应用尤其重视服务的响应速度,希望系统停顿时间最短,以给用户带来较好的体验。

从名字(包含“Mark Sweep”)上就可以看出CMS收集器是基于“标记-清除”算法实现的,它的运作过程相对于前面几种收集器来说要更复杂一些,整个过程分为4个步骤,包括:

初始标记(CMS initial mark)

并发标记(CMS concurrent mark)

重新标记(CMS remark)

并发清除(CMS concurrent sweep)

其中初始标记、重新标记这两个步骤仍然需要“Stop The World”。初始标记仅仅只是标记一下GC Roots能直接关联到的对象,速度很快,并发标记阶段就是进行GC Roots Tracing的过程,而重新标记阶段则是为了修正并发标记期间,因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录,这个阶段的停顿时间一般会比初始标记阶段稍长一些,但远比并发标记的时间短。

由于整个过程中耗时最长的并发标记和并发清除过程中,收集器线程都可以与用户线程一起工作,所以总体上来说,CMS收集器的内存回收过程是与用户线程一起并发地执行。老年代收集器(新生代使用ParNew)

优点:并发收集、低停顿

缺点:产生大量空间碎片、并发阶段会降低吞吐量

采用“标记-清除”算法实现,使用多线程的算法去扫描堆,对发现未使用的对象进行回收。

(1)初始标记

(2)并发标记

(3)并发预处理

(4)重新标记

(5)并发清除

(6)并发重置

特点:响应时间优先,减少垃圾收集停顿时间

适应场景:大型服务器等。

通过JVM参数 -XX:+UseConcMarkSweepGC设置

g1收集器

在G1中,堆被划分成 许多个连续的区域(region)。采用G1算法进行回收,吸收了CMS收集器特点。

特点:支持很大的堆,高吞吐量

--支持多CPU和垃圾回收线程

--在主线程暂停的情况下,使用并行收集

--在主线程运行的情况下,使用并发收集

实时目标:可配置在N毫秒内最多只占用M毫秒的时间进行垃圾回收

通过JVM参数 -XX:+UseG1GC 使用G1垃圾回收器

注意: 并发是指一个处理器同时处理多个任务。 
并行是指多个处理器或者是多核的处理器同时处理多个不同的任务。 
并发是逻辑上的同时发生(simultaneous),而并行是物理上的同时发生。 
来个比喻:并发是一个人同时吃三个馒头,而并行是三个人同时吃三个馒头。

Jmeter压力测试工具

调优总结

初始堆值和最大堆内存内存越大,吞吐量就越高。

最好使用并行收集器,因为并行收集器速度比串行吞吐量高,速度快。

设置堆内存新生代的比例和老年代的比例最好为1:2或者1:3。

减少GC对老年代的回收。

《java学习三》jvm性能优化-------调优的更多相关文章

  1. JVM性能参数调优实践,不会执行Full GC,网站无停滞

    原文来自:http://bbs.csdn.net/topics/310110257 本文只做整理记录,供个人学习. 1 JVM参数调优是个很头痛的问题,设置的不好,JVM不断执行Full GC,导致整 ...

  2. 【初学Java学习笔记】SQL语句调优

    1, 对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2,应尽量避免在 where 子句中对字段进行 null 值判断,创建表时NULL是默认 ...

  3. MySQL性能优化/调优:默认配置的修改

    在这里罗列一下这些配置, 每次新装MySQL的时候, 最好根据实际需要调整一下这些配置: max_connections 最大并发连接数.当MySQL的并发连接达到这个设定值时,新的连接将会被拒绝.当 ...

  4. SQL Tuning / SQL 性能 优化 调优

    Some key concents regarding SQL optimization predicate selectivity (column unique ratio) / cardinali ...

  5. JVM性能优化,提高Java的伸缩性

    很多程序员在解决JVM性能问题的时候,花开了很多时间去调优应用程序级别的性能瓶颈,当你读完这本系列文章之后你会发现我可能更加系统地看待这类的问题.我说过JVM的自身技术限制了Java企业级应用的伸缩性 ...

  6. JVM性能优化, Part 5 Java的伸缩性

    很多程序员在解决JVM性能问题的时候,花开了很多时间去调优应用程序级别的性能瓶颈,当你读完这本系列文章之后你会发现我可能更加系统地看待这类的问题.我说过JVM的自身技术限制了Java企业级应用的伸缩性 ...

  7. JVM性能优化系列-(1) Java内存区域

    1. Java内存区域 1.1 运行时数据区 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域.主要包括:程序计数器.虚拟机栈.本地方法栈.Java堆.方法区(运 ...

  8. JVM性能优化系列-(4) 编写高效Java程序

    4. 编写高效Java程序 4.1 面向对象 构造器参数太多怎么办? 正常情况下,如果构造器参数过多,可能会考虑重写多个不同参数的构造函数,如下面的例子所示: public class FoodNor ...

  9. JVM性能优化系列-(2) 垃圾收集器与内存分配策略

    2. 垃圾收集器与内存分配策略 垃圾收集(Garbage Collection, GC)是JVM实现里非常重要的一环,JVM成熟的内存动态分配与回收技术使Java(当然还有其他运行在JVM上的语言,如 ...

随机推荐

  1. 【Shell】通配符与特殊符号

    ——来自<鸟哥的Linux私房菜> 在 bash 的操作环境中还有一个非常有用的功能,那就是通配符 (wildcard) ! 我们利用 bash 处理数据就更方便了!底下列出一些常用的通配 ...

  2. Microsoft SQL Server 数据库

    1. master 数据库 master 数据库记录 SQL Server 系统的所有系统级别信息.它记录所有的登录帐户和系统配置设置.master 数据库是这样一个数据库,它记录所有其它的数据库,其 ...

  3. 【转】Android Menu

    Menu由两种形式,Option menu和Context menu.前者是按下设备的Menu硬按钮弹出,后者是长按widget弹出. Option Menu 当我们按下Menu的硬件按钮时,Opti ...

  4. Advanced R之编程风格

    转载请注明出处,谢谢.   编程风格指导 好的编码风格如同正确使用标点符号一样重要.没有编码规范仍然可以管理代码,但是有代码规范会使代码更易阅读.如同标点样式,编码规范也有不同.下面描述的是我所使用的 ...

  5. day6 面向对象(2)

    static关键字 1:如果没有static会怎样? 1:定义Person类 1:姓名.年龄.国籍,说话行为 2:多个构造,重载形式体现 2:中国人的国籍都是确定的 1:国籍可以进行显示初始化 cla ...

  6. linux下的函数dirname()和basename()使用

    总览 #include <libgen.h> char *dirname(char *path); char *basename(char *path); 说明 函数以 '/' 为分隔符 ...

  7. ACM-ICPC2018南京网络赛 AC Challenge(一维状压dp)

    AC Challenge 30.04% 1000ms 128536K   Dlsj is competing in a contest with n (0 < n \le 20)n(0<n ...

  8. JQuery EasyUI validate 扩展

    validate 扩展js $.extend($.fn.validatebox.defaults.rules, { equals: { validator: function(value,param) ...

  9. \n和\r\n的区别

    \r是回车符,\n是换行符计算机还没有出现之前,有一种叫做电传打字机(Teletype Model 33)的玩意,每秒钟可以打10个字符.但是它有一个问题,就是打完一行换行的时候,要用去0.2秒,正好 ...

  10. header元素 footer元素 hgroup元素

    header元素 header元素是一种具有引航和导航作用的结构元素, 通常用来放置整个页面或页面内的一个内容区块的标题, 但是也可以包含其他内容, 例如数据表格,搜索表单, 或相关的logo图片 h ...