jvm命令和可视化工具 调优

李克华
云计算高级群: 292870151 195907286 交流:Hadoop、NoSQL、分布式、lucene、solr、nutch
虚拟机:系统虚拟机 程序虚拟机 
系统虚拟机有:VMWare visureBox
程序虚拟机:JVM

JVM:1.类加载子系统(类加载器)2.方法区 3.java堆 4.直接内存 5.java栈 6.本地方法栈 7.垃圾回收系统 8.PC寄存器 9.执行引擎
堆:存储问题 栈:程序运行 方法去:辅助堆栈,解决堆栈的信息产生。
java堆和java程序式比较密切的,几乎所有对象都存在java堆内存中。堆中的内存由GC完全自动管理回收。

堆内存:新生代(刚创建的对象,在堆中存在的时间段)老年代 
新生代:eden(刚产生数据),s0 from区,s1 to区---->大小相等,可以相互转换角色的空间。GC去收集垃圾的时候,java复制算法from区到to区,然后将from区没引用的数据删除,引用的复制到to区,以此迭代回收未引用的对象。新生代每经历一次回收,存活的对象就+1岁,达到一定年龄就成为老年代。

java栈是一块线程私有的内存空间,一个栈,一般由三部分组成:局部变量表,操作数栈,帧数据区。
局部变量表:用户报错函数的参数及局部变量。
操作数栈:主要保存计算过程的结果,计算过程的变量的临时存储空间。

方法区:存储对象字段,方法,常量池,方法区的大小决定了系统可以保存多少类,如果定义过多的类,虚拟机同样报内存溢出异常。
初始堆大小和最大堆大小设置成相等,可以减少GC的次数,提高性能。
Perm:永久区
JVM中最大堆大小由三方面限制:1.操作系统数据模型;系统可用物理内存,系统可用虚拟内存。32
位下,一般限制在1.5-2G.64位无限制。
直接内存广泛应用于NIO中,跳过了堆内存,使java堆可以直接访问原生堆空间。
典型设置:
hotspotJDK:-Xnoclassgc---对无用类进行回收 -verbose:class -XX:+TraceClassLoading查看类的加载信息,在product版虚拟机中使用 -XX:+TraceClassLoading查看类卸
载信息,fastdebug版中使用。在大量使用反射,动态代理,CGLib等bytecode框架的场景,以及动态生成JSP和OSGi这类频频定义ClassLoader的场景都需要虚拟机具备类卸载功能。保证
永久代不会溢出。
  
-verbose:gc 显示详细信息
-XX:MaxDirectMemorySize----直接内存大小,不指定的话默认和java堆的最大值-Xmx一样 -Xmx---最大可用内存 -Xms----初始内存(可以和-Xmx大小相同,避免GC每次回收完毕,重新分配内存) -Xmn----年轻代内存 -Xss--每个线程的堆栈大小jdk5.0后,每个线程堆栈大小位1M,相同物理内存下,减小这个值能生成更多线程,操作系统对进程内的线程有限制,经验值是3000-5000 -XX:NewRatio---设置年轻代(包括Eden和2个Survivor区)和老年代的比值,如果设置为4,那么年轻代:年老代=1:4 -XX:SurvivorRatio---设置年轻代中Eden与Survivor区的大小比值,如果为4,则2个Survivor区与Eden区的比值是2:4,一个Survivor占1/6 -XX:PermSize--设置持久代大小 -XX:MaxPermSize---设置持久代最大(方法区)内存 -XX:MaxTenuringThreshold---设置垃圾最大年龄。如果是0,年轻代步经过Survivor区,直接进入老年区。对于老年代较多的应用,可以提高效率。如果设置较大值,那么年轻代对象在Survivor区进行多次复制,可以增加对象在年轻代的存活时间,增加年清代即被回收的概率。 -XX:HeapDumpOnOutOfMemoryError---内存溢出时导出整个堆内存信息 -XX:HeapDumpPath---设置导出堆内存信息的存放目录 -XX:MaxDirectMemorySize--默认为最大堆内存的空间=Xmx.达到上限会触发垃圾回收,不能释放空间就OOM。 -XX:MaxTenuringThreshold--对象再经历多少次GC后进入老年去--默认15 -XX:PretenureSizeThreshold--对象超过多少直接进入老年代,只对Serial和ParNew收集器有效。 -Xloggc:d:/gc.log---将日志打印到一个文件中 TLAB: -XX:+UseTLAB---使用TLAB -XX:+TLABSize---设置TLAB大小 -XX:TLABRefillWasteFraction---设置进入TLAB空间单个对象的大小---默认64即1:64。如果单个对象大于整个空间的1/64,则再堆中创建对象。 -XX:+PrintTLAB查看TLAB信息 -XX:ResizeTLAB自调整TLABRefillWasteFraction的阈值。 -XX:-DoEscapeAnalysis---禁用逃逸分析,想看TLAB的打印结果,必须禁用此项。 ParNewGC: -XX:+UseParNewGC开启parnewe回收器,新生代垃圾收集器 -XX:ParallelGCThreads---指定parnew回收器的线程数,一般和计算机CPU核数相当,否则过多会影响计算机的性能。 ParallelGC: -XX:MaxGCPauseMilli---设置GC最大停止时间,根据业务判定过小,会增加GC次数。 -XX:GCTimeRatio---默认99,回收垃圾时间不超过1/(1+99). -XX:+UseAdaptiveSizePolicy---并行垃圾回收器parallel回收器打开自适应模式,系统自动调节eden,from,to比例,和到老年代的判定年龄。以求达到平衡点。 ParallelOldGC: -XX:+UseParallelGC----设置并行老年代垃圾回收器 -XX:+ParallelGCThreads----设置垃圾收集时的线程数量。 CMS: --XX:+UseConcMarkSweepGC---开启CMS并发标记清除,作用在老年代,和新生代Serial,ParNew收集器搭配使用。 --XX:ConcGCThreads---设置CMS线程数 --XX:CMSInitiatingOccupancyFraction---老年代内存达到默认68%比率,CMS开始工作,但会造成应用程序停顿。---依据业务情况调节。 --XX:+UseCMSCompactAtFullCollection---开启CMS整理碎片功能,CMS执行完后会执行一次整理。 --XX:CMSFullGCsBeforeCompaction---设置CMS执行次数到多少,进行一次内存压缩。 GC: --XX:+UseG1GC---开启G1收集器 --XX:MaxGCPauseMillis---指定最大停止时间。 --XX:ParallelGCThreads---设置G1并行线程数。 内存分析工具:memoryanalyzer 1.5.0 可以和tomcat集成 aaa - http://download.eclipse.org/mat/1.5/update-site(eclipse插件下载) JVM堆内存大小=年轻代大小+年老代大小+Perm大小(一般固定64M)。增大年轻代会减小年轻代大小,sun建议是3/8. 并行收集器:以达到一定吞吐量为目标,适用于科学技术和后台处理。 串行收集器:JDK1.5之前默认的收集器。 响应时间优先的并发收集齐:主要应用于保证系统的相应时间,减少垃圾收集时的停顿时间,适用于服务器,电信领域。 新生代是最不稳定的。老年代是对象使用比较稳定才进入了老年代。如果系统多是一直要使用的对象,老年代应调大,如果,对象更新比较频繁的化,新生代应设置大点。 初始化内存和新生代内存大小不能冲突。 新生代和from区的比值,新生区和老年代的比值 SurvivorRatio=Eden/from=Eden/to NewRatio=Perm/NewRatio NewRatio一般设置到堆内存的1/3 到1/4 JVM2中模式:1.Client模式2.Server模式 java -version可以查看。 GC: garbage Collection 垃圾:特质存在于内存中,不再被引用的对象。 垃圾回收的算法:引用计数器,标记压缩法,复制算法,分代,分区的思想。 引用计数法:古老而经典的垃圾回收算法,当对象被引用,计数器+1,对象失去引用,计数器-1.当计数器=0时,对象未被引用,垃圾回收器回收。缺点:1.无法处理类似递归的循环引用的情况,如父类包子类,子类再包子类。2.每次加减操作比较浪费系统。 标记清楚法:堆中对象被引用,做标记,遍历堆内存,回收内存未标s记的内存。缺点:容易造成内存碎片,回收不干净。不连续的内存运行速度低于连续的内存运行速度。随着碎片内存过多,会严重拖累系统性能。 复制算法:from区到to区 eden区的对象被GC回收1次,年龄增加1岁。移动到from区。s1区,s0区大小相等,角色可以相互转换同时只有一块被使用。GC再s0,s1的工作是:被引用的对象先复制到s1,然后清空s0中未被引用的对象。eden区是初始化对象的区域。 标记压缩法:老年区使用的GC算法。 新生代和老年代中回收对象的量一般是不一样的。为什么老年代使用标记压缩方法:老年代中的对象是比较稳定的,GC每次可能只回收一少部分对象。如果老年代采用复制法,会特别耗内存,不断复制会影响系统性能。 分代算法:根据对象的特点把内存分成N块,针对不同的内存特点使用不同的算法。例如:新生代,老年代就使用了这种算法。 分区算法:1.7以后提出的。主要是讲内存分为多个区域,每个区域都可以独立的进行GC。这样可以细粒度的操作内存区域。 垃圾回收再大部分情况下,都会要求应用程序进入一个短暂的停顿状态,以便更好的回收内存垃圾。 如果没有GC介入,对象不会离开eden区,一般来讲,新生代中的对象达到一定年龄会自动进入老年代。对象的年龄是由对象经历GC的次数决定的。 JVM默认的GC:PSYoungGen 还有串行的垃圾回收机制:UseSerialGC 大对象会直接进入老年代,由参数可以设置阈值。 TLAB:Thread Local Allocation Buffer 栈分配,即线程本地分配缓存。每一个线程都会产生一个TLAB,该线程独享,工作区域。java使用TLAB区避免多线程冲突的问题。对象太大直接使用堆,不大的使用TLAB 尝试栈--->TLAB---->老年代---->eden (均不满足的情况下才会直线走下去分配,满足就停止) tomcat.exe可以配置Jvm参数。 java垃圾回收器:1.串行垃圾回收期2.并行垃圾回收器3.CMS回收期(1.7jdk)4.G1回收器 串行垃圾收集器:使用单线程回收,对于并行能力弱的服务器,使用串行。根据作用不同,分为新生代串行和老年代串行回收器。使用-XX:UseSerialGC开启串行垃圾回收器。 并行垃圾回收器:创建多个线程进行垃圾回收,有效缩短垃圾回收时间。 并行回收器-----ParNew回收器;工作在新生代的垃圾回收器,只是简单讲串行回收器多线成化,回收策略和串行回收器一样。-XX:+UseParNewGC开启parnewe回收器,老年代则使用串行回收器。-XX: 并行回收器-----ParrelGC;作用于新生代,使用的时复制算法。多线程执行,关注点是高吞吐量。-XX:MaxGCPauseMilli---设置GC最大停止时间,根据业务判定过小,会增加GC次数。 并行回收器-----ParallelGC:使用标记压缩法,关注吞吐量。 并发标记清除:Concurrent Mark Sweep不会造成应用停顿,回收垃圾的时候应用程序同时运行。CMS以来年代内存使用率启动GC,默认68%。如果CMS再回收过程中内存不足,JVM启动 老年代串行回收器,此时会产生较长停顿。对于标记清除的碎片问题,通过设置内存压缩,CMS内存整理功能 G1垃圾回收器---GarBageFirst,jdk1.7提出的,使用了分区算法。并行性,并发性:可与应用程序同时执行,不会完全阻塞应用程序。区别于其他垃圾回收器在独代区工作,G1是兼顾年轻代和老年代。G1采用复制对象的方式,减少碎片。G1选取部分分区回收,提高了性能。 Tomcat:使用tomcat。Jmeter--jmeter从入门到精通 http://jmeter.apache.org/download_jmeter.cgi 对Tomcat增加压力,设置不同的JVM参数。。 实验测压----初始内存增大,GC次数减少,提高了性能。

  

常用命令:

jps
jstat 虚拟机统计信息监视工具
jinfo java配置信息工具
jmap java内存映像工具
jhat 虚拟机堆转储快照分析工具
jstatk 堆栈跟踪工具

jdk可视化工具
jconsole:java监视和管理控制
visualVM:多合一故障处理工具

原文地址:https://www.cnblogs.com/huiandong/p/9473880.html