概述

JVM主要是对象的创建回收等,而其他方面的调优主要应该是由java程序员来实现,所以常见的java调优,无非就是调整jvm进程所能够使用的内存空间。



JVM运行时由classloader装载类,装载之后开始在内存中部署并运行真正的执行过程是由执行引擎执行的,而执行引擎运行时有可能还要调用本地方法,所以java程序如果书写中有本地方法调用的话,则与本地方法库建立联系,而我整个JVM的内存空间大体上分为上图中下面方框中的五个组成部分

方法区

堆内存(方法区和堆内存是占用空间最大的,尤其是堆内存,java的各种对象多存储在堆内存中, 所以所谓的调优也主要是对堆内存进行调整

JVM栈

本地方法栈

程序计数器寄存器

JVM管理的内存段可分为两大类:线程共享内存和线程私有内存

java实现多任务管理的时候,内部线程实现,有些是守护线程有些是工作线程,守护线程主要是跟jvm自身运行管理相关的,jvm其实就是模拟了一个计算机运行的环境包含了abi和api,所以在任何的jvm内部都是全状态的一个虚拟的程序运行环境。

线程共享内存

  1. 方法区:存储jvm加载的class、常量、静态变量、即使编译器编译后的代码等
  2. java堆:存储java的所有对象实例、数组等

线程私有内存

  1. 程序计数寄存器:每个线程有自己的计数寄存器,存储当前线程执行字节码的地址
  2. jvm栈:jvm会为每个运行此案城分配一个栈区,线程调用方法时和方法返回时会进行入栈和出栈的操作
  3. 本地方法栈区:与jvm stack类似,只不过此区域是调用本地方法服务



重点关注共享内存



Java HotSpot 虚拟机选项 -X -XX 的含义

-x -xx通常是用来保存这些内存区域的配置、状态数据,一个变量的打头选项。

Options that begin with -X are non-standard (not guaranteed to be supported on all VM implementations), and are subject to change without notice in subsequent releases of the JDK.

以 -X 开头的选项是非标准选项(不能保证被所有的 JVM 实现都支持),并且在 JDK 的后续版本中不需要通知就可以进行更改。

Options that are specified with -XX are not stable and are subject to change without notice.

以 -XX 指定的选项是不稳定的,并且会在没有通知的情况下进行更改,会根据当前jvm内部的运行特征不断的发生变化。

这些数据的获取可用通过 jinfo -flages 进行获取

//只要安装了jdk
//获取任意指定的标志的相关信息
➜  ~ jinfo -h
Usage:
    jinfo [option] <pid>
        (to connect to running process)
    jinfo [option] <executable <core>
        (to connect to a core file)
    jinfo [option] [server_id@]<remote server IP or hostname>
        (to connect to remote debug server)

where <option> is one of:
	//用于显示任意指定的标志的相关信息(vm flag的值)
	//这些值有的以-x开头有的以-xx开始
    -flag <name>         to print the value of the named VM flag
    //禁用某个flag
    -flag [+|-]<name>    to enable or disable the named VM flag
    //设置某个flag的值
    -flag <name>=<value> to set the named VM flag to the given value
    -flags               to print VM flags
    -sysprops            to print Java system properties
    <no option>          to print both of the above
    -h | -help           to print this help message
jps
1234  xxxx
jinfo -flags  1234 即可查看进程xxxx在启动进程时候的某些选项

Java Heap SIze Options



堆内存相关的选项:

-xx:NewsSize

-xx:MaxNewSize

-xx:SurvivorRatio

-Xms

-Xmx

The memory structure of a JVM process



-Xms:JVM已启动就需要立即分配的堆内存空间,即堆内存空间初始化大小(堆内存空间不包括持久代)

-Xmx:新生代加上新生代预留,老年代加上老年代预留(reserved),堆内存空间的最大值

-XX:NewSIze:新生代初始化空间 ,所以(-Xms)-(-XX:NewSIze)=老年代的初始化大小

-XX:MaxNewSize:新生代最大值,(-XX:MaxNewSize)-(-XX:NewSIze)= 新生代reserved,(-Xmx)-(-XX:MaxNewSize)=老年代最大空间值,(-Xmx)-(-XX:MaxNewSize)-(-Xms)-(-XX:NewSIze)=老年代reserved

-XX:MaxPerSize:持久代的最大值

-XX:PermSize:持久代的初始化值

-XX:ServivorRatio:Eden/survivor eden和(from+to)的比例

摘录

常见配置汇总

堆设置

-Xms:初始堆大小

-Xmx:最大堆大小

-XX:NewSize=n:设置年轻代大小

-XX:NewRatio=n:设置年轻代和年老代的比值。如:为3,表示年轻代与年老代比值为1:3,年轻代占整个年轻代年老代和的1/4

-XX:SurvivorRatio=n:年轻代中Eden区与两个Survivor区的比值。注意Survivor区有两个。如:3,表示Eden:Survivor=3:2,一个Survivor区占整个年轻代的1/5

-XX:MaxPermSize=n:设置持久代大小

收集器设置

-XX:+UseSerialGC:设置串行收集器

-XX:+UseParallelGC:设置并行收集器

-XX:+UseParalledlOldGC:设置并行年老代收集器

-XX:+UseConcMarkSweepGC:设置并发收集器

垃圾回收统计信息

-XX:+PrintGC

-XX:+PrintGCDetails

-XX:+PrintGCTimeStamps

-Xloggc:filename

并行收集器设置

-XX:ParallelGCThreads=n:设置并行收集器收集时使用的CPU数。并行收集线程数。

-XX:MaxGCPauseMillis=n:设置并行收集最大暂停时间

-XX:GCTimeRatio=n:设置垃圾回收时间占程序运行时间的百分比。公式为1/(1+n)

并发收集器设置

-XX:+CMSIncrementalMode:设置为增量模式。适用于单CPU情况。

-XX:ParallelGCThreads=n:设置并发收集器年轻代收集方式为并行收集时,使用的CPU数。并行收集线程数。

调优总结

年轻代大小选择

响应时间优先的应用:尽可能设大,直到接近系统的最低响应时间限制(根据实际情况选择)。在此种情况下,年轻代收集发生的频率也是最小的。同时,减少到达年老代的对象。

吞吐量优先的应用:尽可能的设置大,可能到达Gbit的程度。因为对响应时间没有要求,垃圾收集可以并行进行,一般适合8CPU以上的应用。

年老代大小选择

响应时间优先的应用:年老代使用并发收集器,所以其大小需要小心设置,一般要考虑并发会话率和会话持续时间等一些参数。如果堆设置小了,可以会造成内存碎片、高回收频率以及应用暂停而使用传统的标记清除方式;如果堆大了,则需要较长的收集时间。最优化的方案,一般需要参考以下数据获得:

并发垃圾收集信息

持久代并发收集次数

传统GC信息

花在年轻代和年老代回收上的时间比例

减少年轻代和年老代花费的时间,一般会提高应用的效率

吞吐量优先的应用

一般吞吐量优先的应用都有一个很大的年轻代和一个较小的年老代。原因是,这样可以尽可能回收掉大部分短期对象,减少中期的对象,而年老代尽存放长期存活对象。

较小堆引起的碎片问题

因为年老代的并发收集器使用标记、清除算法,所以不会对堆进行压缩。当收集器回收时,他会把相邻的空间进行合并,这样可以分配给较大的对象。但是,当堆空间较小时,运行一段时间以后,就会出现“碎片”,如果并发收集器找不到足够的空间,那么并发收集器将会停止,然后使用传统的标记、清除方式进行回收。如果出现“碎片”,可能需要进行如下配置:

  1. -XX:+UseCMSCompactAtFullCollection:使用并发收集器时,开启对年老代的压缩。
  2. -XX:CMSFullGCsBeforeCompaction=0:上面配置开启的情况下,这里设置多少次Full GC后,对年老代进行压缩

垃圾回收的瓶颈

传统分代垃圾回收方式,已经在一定程度上把垃圾回收给应用带来的负担降到了最小,把应用的吞吐量推到了一个极限。但是他无法解决的一个问题,就是Full GC所带来的应用暂停。在一些对实时性要求很高的应用场景下,GC暂停所带来的请求堆积和请求失败是无法接受的。这类应用可能要求请求的返回时间在几百甚至几十毫秒以内,如果分代垃圾回收方式要达到这个指标,只能把最大堆的设置限制在一个相对较小范围内,但是这样有限制了应用本身的处理能力,同样也是不可接收的。

分代垃圾回收方式确实也考虑了实时性要求而提供了并发回收器,支持最大暂停时间的设置,但是受限于分代垃圾回收的内存划分模型,其效果也不是很理想。

为了达到实时性的要求(其实Java语言最初的设计也是在嵌入式系统上的),一种新垃圾回收方式呼之欲出,它既支持短的暂停时间,又支持大的内存空间分配。可以很好的解决传统分代方式带来的问题。

摘自:https://www.cnblogs.com/andy-zhou/p/5327288.html#_caption_19

Tomcat负载均衡、调优核心应用进阶学习笔记(四):JVM调优的更多相关文章

  1. Tomcat负载均衡、调优核心应用进阶学习笔记(一):tomcat文件目录、页面、架构组件详解、tomcat运行方式、组件介绍、tomcat管理

    文章目录 tomcat文件目录 bin conf lib logs temp webapps work 页面 架构组件详解 tomcat运行方式 组件介绍 tomcat管理 tomcat文件目录 ➜ ...

  2. Tomcat负载均衡、调优核心应用进阶学习笔记(二):Tomcat前世今生、安装、配置文件详细说明、tomcat应用程序部署、webapp 体系结构、tomcat运行方式

    文章目录 Tomcat前世今生 安装 配置文件详细说明 tomcat应用程序部署 webapp 体系结构 tomcat运行方式 Tomcat前世今生 java体系: 1 java程序设计语言 2 ja ...

  3. Tomcat负载均衡、调优核心应用进阶学习笔记(三):LNMT nginx+tomcat、LAMT apache+tomcat、session会话保持、不错的站点

    文章目录 LNMT nginx+tomcat LAMT apache+tomcat 基于mod_proxy 单节点 配置基于mod_proxy的负载均衡 基于mod_jk(需要编译安装) 单节点 配置 ...

  4. Tomcat负载均衡、调优核心应用进阶学习笔记(五):Tomcat调优和Tomcat监控(差评)

    文章目录 tomcat调优 tomcat监控 tomcat调优 vi catalina.sh # --------------------------------------------------- ...

  5. MYSQL进阶学习笔记四:MySQL存储过程之定义条件,处理过程及存储过程的管理!(视频序号:进阶_11,12)

    知识点五:MySQL存储过程之定义条件和处理过程及存储过程的管理(11,12) 定义条件和处理: 条件的定义和处理可以用来定义在处理过程中遇到的问题时相应的处理步骤. DECLARE CONTINUE ...

  6. 介绍一下再Apache下的Tomcat负载均衡的一些使用问题

    在负载均衡技术中,硬件设备是比较昂贵的,对于负载均衡的学习者如果不是在企业中应用或者是学员中学习,很少有机会能碰到实际操作的训练.(http://xz.8682222.com)所以,很多朋友都会选择软 ...

  7. Linux下Nginx+Tomcat负载均衡和动静分离配置要点

    本文使用的Linux发行版:CentOS6.7 下载地址:https://wiki.centos.org/Download 一.安装Nginx 下载源:wget http://nginx.org/pa ...

  8. 基于apache的tomcat负载均衡和集群配置

    最近不是很忙,用零碎时间做点小小的实验. 以前公司采用F5负载均衡交换机,F5将请求转发给多台服务器,每台服务器有多个webserver实例,每个webserver分布在多台服务器,交叉式的分布集群. ...

  9. Nginx+tomcat负载均衡时静态页面报404

    百度到的问题解决BLOG http://os.51cto.com/art/201204/326843.htm nginx+2台tomcat负载均衡,应用程序已部署,单独访问tomcat时,可以访问到所 ...

随机推荐

  1. Volatile 只保证可见性,并不保证原子性

    [尊重原创,转载请注明出处]http://blog.csdn.net/guyuealian/article/details/52525724   在说明Java多线程内存可见性之前,先来简单了解一下J ...

  2. 华为要卖5G技术,虽然我和华为没有一点关系,但是我也很呵呵

    http://www.sohu.com/a/340555529_166680 老任头,竟然说出了这样的话,要卖5G技术给西方,然后塑造对手. 按照老任头的脾气,老任头应该不至于胡说八道这样的话,但是呢 ...

  3. android 查看网络图片

    public class MainActivity extends Activity { private EditText pathText; private ImageView imageView; ...

  4. 自定义checkbox(对勾)和radio样式

    checkbox: html: <div> <label class="unSelected selected" for="choose"&g ...

  5. SQL如何使用快照恢复之前的数据

    什么是快照 数据库快照是SQL server 2005的一个新功能.给出的定义如下 数据库快照是数据库的只读静态视图.在创建时每个数据库快照在事务上都与源数据库一致.在创建数据库快照时,源数据库通常会 ...

  6. go语言从例子开始之Example25.通道方向

    当使用通道作为函数的参数时,你可以指定这个通道是不是只用来发送或者接收值.这个特性提升了程序的类型安全性. Example: package main import "fmt" / ...

  7. java基础之轻松搞定反射

    前言 java的名词太古怪.反射白话文解释,就是把一个字符串的类名,实例化,少了个new单词. 反射步骤 准备一个苹果类像这个样子. public class PingGuo { private St ...

  8. 如何加快Vue项目的开发速度

    如何加快Vue项目的开发速度 本文摘自奇舞周刊,侵权删. 现如今的开发,比如内部使用的管理平台这种项目大都时间比较仓促.实际上来说,在使用了webpack + vue 这一套来开发的话已经大大了提高了 ...

  9. jenkins连接gitlab,提示returned status code 128,附解决办法

    在项目中配置git仓库地址,报无权限 Failed to connect to repository : Command "D:\Program Files\Git\mingw64\bin\ ...

  10. Spark开发环境搭建和作业提交

    Spark高可用集群搭建 在所有节点上下载或上传spark文件,解压缩安装,建立软连接 配置所有节点spark安装目录下的spark-evn.sh文件 配置slaves 配置spark-default ...