系统和虚拟机jvm调优一日一记_第1页
系统和虚拟机jvm调优一日一记_第2页
系统和虚拟机jvm调优一日一记_第3页
系统和虚拟机jvm调优一日一记_第4页
系统和虚拟机jvm调优一日一记_第5页
已阅读5页,还剩28页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

一、同 synchronized关键 同步方 同步代码 锁的底层实 锁的种 volatile关键 AtomicXxx类型 锁的重 公平 二、同步容 三、 四、JVM优 JVM简单结构 类加载子系统与方法区 Java 直接内 回收系 Java 本地方法 PC寄存 执行引 什么是分代,分代的必要性是什 分代的划 收集器的分 常见回收算 分代收集 JVM优 JDK常用JVM优化相关命 JVM常见参 Java并发编一、同synchronizedthisClass同步方synchronizedT同步方法锁定的是当前对象。当多线程通过同一个对象多次调用当前同步方法时,同步代锁定临界对T}锁定当前对T}this1.1锁的底层实Java虚拟机中的同步(Synchronization)基于进入和退出管程(Monitor)对象实现。同步方monitorentermonitorexit指令来实现同步的,而是由方法调用指令运行时常量池中方法的ACC_SYNCHRONIZED标志来隐式实现的。对象内存简r元数据,JVM通过这个指针确定该对象是哪个类的实例等信息。synchronized同步方法或同步代码monitor对象(也称为管程或监视器锁)的起始地址。每个对象都存在着一个monitor与之关联,对象与其monitor之间的关系有monitor可以与对象一起创建销毁或当线程试图获取对象锁时自动生成,但当一个monitor被某个线程持有后,它便处于锁定状态。Java虚拟机(HotSpot)中,monitorObjectMonitor.时间片结束或thread.object.notify()/object在定义中,锁池和等待队列都属于阻塞状态当多线程并发同一个同步代码时,首先会进入_EntryList,当线程获取锁标记后,(+1其他线程在_EntryListwaitmonitor中的计数器执行null0计算。锁的种Java重量级1.3偏向JMynchedMonir中有变量AHONIZE的。提高效率。轻量级自旋当获取锁的过程中,未获取到。为了提高效率,JVM自动执行若干次空循环,再次申请volatile关键CPUCPU计算缓存中,当CPU计算中断时,有可能刷新缓存,重新内存中的数据。程运行的过程修饰的变量是线程可见的JVM解释volatile修饰的变量时会通知CPU,在计算过程中,CPU缓volatile只是通知底层计算时,CPU检查内存数据,而不是让一个变量在多个线程中同AtomicIntegeri=newAtomicInteger(0);if(i.get()!=5) 在上述代码中,getincrementAndGetCountDownLatch门concurrent0时,await阻塞线程可执行。锁的重Java中,同步锁是可以重入的。只有同一线程调用同步方法或执行同步代码块,对码,且同步代码的锁对象相同时,monitor中的计数器继续递增。每个同步代码执行结束,放锁标记,_Ownernull。synchronizedJDK1.5JDK1.7版本后,优化效率已经非常好reentrantLock差多少。使用重入锁,必须必须必须手工释放锁标记。一般都是在finally代码块中定义释放锁标unlock方法。公平公平锁会记录t1获取锁,t2t35t1t3remove线程执行线程执行ID。二、同步容解决并况下的容器线程安全问题的。给多线程环境准备一个线程安全的容器对象。VectorHashtablesynchronized方concurrentnative。Java8CAS。synchronized低。keyvaluenull。写时集合写入效率低效率高每次写入数据都会创建一个新的底层数组0add方法在容量不足的时候,抛出异常。put方法在容量不足的时候,阻塞等待。offer方法,

offerfalse。当前新增数据操作放弃。(ofer(aluetimestimeunit)timeunitfalse。transferaddput三、Runnablerun方法无返回值。-voidExecutor接口的子接口。提供了一个新的服务方法,submit。有返回值(Future类型。submitoverloadRunnable的,不需要提供返回值的;Callable,可以提供线程执行后的返回值。voidexecute(Runnable)Futuresubmit(Callable)FutureRunningShuttingDownTermitnaedRunning-线程池正在执行中。活动状态。-Terminated-常用方法:Tget() Tget(long,TimeUnit)call。callRunnable中的run方法完全一致。call接口方法Objectcall();相当于Runnable接口中的run方法区别为此方法有返回值。Runnable-Callable,其他情况可1等各种线程池。JVM一致。当开启线程池后,直到JVM关闭为止,是线程池的默认生命周期。如果手工调用shutdown方法,那么线程池-JVMshutdown并处理完所有的任务。Arrays,Collections等工具类型的功用。BlockingQueue<Runnable>作为任务的载体。当任务数量大于线程是有线程支持上限。不能随意的提供线程池。PC2001000~10000queuedtasks-任务队列completedtasks-(Intege.MAX_AUE创建新的线程。当线程池中的线程空闲时长达到一定的临界值(60秒,自动释放线60应用场景:内部应用或测试应用。内部应用有条件的内部数据瞬间处理时应用信心scheduleAtFixedRate(Runnable,start_limit,limittimeunit)runnable-要执行的任务。start_limit-limit-timeunit-(DelaydQueue理,没整理,每天整理等。分支合并线程池(mapduce类似的设计思想。适合用于处理复杂任务。初始化线程容量与CPU数相关。(ecueask,ecueActiForkJoinPool-(Callable/Runnable)compute方法:就是任务的执行逻辑。ForkJoinPool1个线程。根据任务自动的分支新的子线程。forkjoin两个方法实现的。初始化线程容量与CPU数相关。此线程池中的是精灵线程ForkJoinPoolpublic(intcorePoolSize,//容量,创建线程池的时候,默认有多少线程。也是线程池保持 umPoolSize,//longkeepAliveTime,//生命周期,0TimeUnitunit,//BlockingQueue<Runnable>workQueue//任务队列,阻塞队列。注意,泛型必须是4,最大线程数20030秒。四、JVM优JVM简单结构类加载子系统与方法区符串字面量和数字常量(Class文件中常量池部分的内存映射。Javajavajava程序最主要的内存工作区域。几乎所有的javajavajava应用密切相直接内javaNIOjavajava堆外的、直接向系统申java堆外,因此它的大小不会直接受限于回收系,回收系统是java虚拟机的重要组成部分回收器可以对方法区、java堆和直接内存进行回收。其中,java堆是收集器的工作重点。和C/C++不同,java中所有的对象空间释放都是隐式的,也就是说,java中没有类似()delete()这样的函数释放指定的释放对象,完成包括java堆、方法区和直接内存中的全自动化管理。,Java每一个java虚拟机线程都有一个私有的java栈,一个线程的java栈程创建的时候本地方javajava栈用于方法的调用,而本地方法java虚拟机的重要扩展,javajava直接调用本地方法(C编写)PC寄存方法称为当前方法。如果当前方法不是本地方法,PC寄存器就会指向当前正在被执行的指PCundefined执行引执行引擎是java虚拟机的最组件之一,它负责执行虚拟机的字节码,现代虚拟机为了提高执行效率,会使用即时编译(justintime)技术将方法编译成机器码后再执行。JavaHotSpot JavaHotSpotServerVM(-server),为在服务器环境中最大化程序执行速度而设计的执行Java Server 模式的时候,使用的是一个代号为C1的轻量级编译器,而-server模式启动的虚拟机采用相对重量级,代号为C2的编译器.C2比C1编译器编译的相对彻底,服JDK安 版本且是64位系统应用时 无效--64-server---32-server-注意:在部分JDK1.6版本和后续的JDK版本(64位系统)中,- 了,Server模式成为唯一堆结构及对象分什么是分代,分代的必要性是什Java虚拟机根据对象存活的周期不同,把堆内存划分为几块,一般分为、老年代和永久代(HotSpot虚拟机而言JVM的内存分代策略。堆内存是虚拟机管理的内存中最大的一块,也是回收最频繁的一块区域,我们程序所有的对象实例都存放在堆内存中给堆内存分代是为了提高对象内存分配和回收的效一起,随着程序的执行,堆内存需要频繁进行收集,而每次回收都要遍历所有的对象,GC效率。,有了内存分代情况就不同了新创建的对象会在中分配内存经过多次回收然存的对象存放在老年代中静态属性类信息等存放在永久代中中的对存活时间短只需要在区域中频繁进行老年代中对象生命周期长内存回收频率相对较低不需要频繁进行回收永久代中回收效果太差一般不进行回收还以根据不同年代的特点采用合适的收集算法分代收集大大提升了收集效率这些都内存分代带来的好处。,分代的Java虚拟机将堆内存划分为、老年代和永久代,永久代是HotSpot虚拟机特有的概念(JDK1.8metaspace替代永久代,它采用永久代的方式来实现方法区,其他的HotSpotJDK1.7HotSpot已息、静态变量等数据,与回收关系不大,和老年代是回收的主要区域。2.2.1(Young新生成的对象优先存放在中,对象朝生夕死,存活率很低,在中,常规应用进行一次收集一般可以回收70%~95%的空间,回收效率很高。HotSpot将划分为三块,一块较大的Eden(伊甸)空间和两块较小的Survivor(幸存者)空间,默认比例为8:1:1。划分的目的是因为HotSpot采用算法来回收,MinorGC。留区域。GC进行时,Eden区中所有存活的对象都会被到ToSurvivor区,而在FromSurvivor区中,仍存活的对象会根据它们的值决定去向,值达到阀值(默认为15,中的对象每熬过一轮回收,值就加1,GC分代在对象的header中)的对象会被移到老年代中,没有达到阀值的对象会被到ToSurvivor区。接着清空Eden区和FromSurvivor区,中存活的对象都在ToSurvivor区。接着,FromSurvivorToSurvivorToSurvivorGCFromSurvivorFromSurvivorGCToSurvivor区,总之,不管怎样都会保证老年代(Old在中经历了多次(具体看虚拟机配置的阀值)GC后仍然存的对象会进入永久代(Permanent言,Java虚拟机规范可以不进行收集,一般而言不会进行回收。 回收算法及分代收集 收集器的分次收集ScavengeGC,指发生在的GC,因为的Java对象大多都是朝生夕死,所以ScavengeGC。一般情况下,当新对象生成,并且在Eden申请空间失败时,就会触发ScavengeGC,对EdenEdenEdenGC会频繁Eden去能尽快空闲出来。全收集FullGC,指发生在老年代的GC,出现了FullGC一般会伴随着至少一次的MinorGC(老,FullGC。System.gc()方法来显式的启动全收集回收器的常规匹ParallelSerialParallel常见回收算3.2.1计数(Reference。少一个计数回收时,只用收集计数为0的对象。此算法最致命的是无法处理循环。3.2.2。此算法把内存空间划为两个相等的区域,每次只使用其中一个区域回收时,遍历。标记-清除(Mark-标记-整理 节点开始标记所有被对象,第二阶段遍历整个堆,把清除未标记对象并且把存活对象免了“”算法的空间问题。简图如下:分代收集串行收集器Serial收集器是Hotspot运行在模式下的默认收集器,它的特点是只用一个CPU(计算)/一条收集线程去完成GC工作,且在进行收集时必须暂停其他所有的工作线程(“StopTheWorld”-STW)。可以使用-XX:+UseSerialGC打开。虽然是单线程收集,但它却简单而高效,VM管理内存不大的情况下(M~一两百M的),停顿时间完全可以控制在几十毫秒~一百多毫秒内。并行收集器ParNewSerial的多线程版本GC外,Serial是VM启用CMS收集器-XX:+UseConcMarkSweepGC的默认收集器)。由于存程切换的开销,ParNew在单CPU的环境中比不上Serial,且在通过超线程技术实现的两个CPU的环境中也不能100%保证能Serial.但随着可用的CPU数量的增加,收集效率肯定也会大大增加(ParNewCPU的数量相同,CPU数量过大的环境中,可用-XX:ParallelGCThreads=<N>GC线程数)。与ParNew类似,ParallelScavenge也是使用算法,也是并行多线程收集器.但与其他收集器关注尽可能缩短收集时间不同,ParallelScavenge更关注系统吞吐量:系统吞吐量=运行用户代码时间/(运行用户代码时间+收集时间停顿时间越短就越适用于用户交互的程序-良好的响应速度能提升用户的体验;而高吞吐量则适用于运算而不需要太多交互的任务-可以最高效率地利用U时间,尽快地完成程序的运算任务aallelene提供了如下参数设置系统吞吐量:ParallelScavenge-(毫秒数)超过设定值,GC的频率增加-(整数:0<GCTimeRatio<100)是收集时间占总XX:+UseAdaptiveSize启用GC自适应的调节策略:不再需要手工指定-Xmn、-XX:SurvivorRatio、-XX:PretenureSizeThreshold等细节参数,VM会根据当前系统的运行情况收集性能信息,SerialOld收集SerialOldSerial收集器的老年代版本,同样是单线程收集器,使用“标记-ParallelOld收集ParallelOldParallelScavenge收集器的老年代版本,使用多线程和“标记-整理”算法,吞吐量优先,ParallelScavengeCPU资源敏感系统内使用;CMS收集器(ConcurrentMarkCMS(ConcurrentMarkSweep)收集器是一款具有划时代意义的收集器,一款真正意义上的并发收集器,G1收集器,但现在主流互联网企CMS(如、微店).基于”标记-清除”算法实现,GC4个步骤初始标记(CMSinitial并发标记(CMSconcurrentmark:GCRootsTracing过程重新标记(CMS并发清除(CMSconcurrentsweep:已死对象将会就地释放,注意:此处没有压缩能直接关联到的对象,速度很快;而重新标记则是为了修正并发标记期间因用户程序继续运行而导致标记产生变动的那一部分对象的标记记录,虽然一般比初始标记阶段稍长,但要远CMSCMS默认启动的回收线程数=(CPU数目CPU数>4时GC25%CPU资源,CPU数<=4时,GC线CPU资源,从而导致应用程序变慢,总吞吐量降低.无法处理浮动,可能出现PromotionFailure、ConcurrentModeFailure而导致另一次FullGC的产生:浮动是指在CMS并发清理阶段用户线程运行而产生的新.由于GC阶段用户线程还需运行,因此还需要预留足够的内存空间给用户线程使用,CMS不能像其他收集器那样等到老年代几乎填满了再进行收集.因此CMS提供了-XX:CMSInitiatingOccupancyFraction参数来设置GC的触发百分比(以及-XX:+UseCMSInitiatingOccupancyOnly来启用该触发百分比),当老年代的使用空间超过该比例后CMS就会被触发(JDK1.6之后默认92%).但当CMS运行期间预留的内存程序需要PromotionFailure等失败,VM将启动后备预案:SerialOldFullGC(CMS通常配合大内存使用,SerialGC,那最后,CMS采用”标记-清除”算法实现,可能会产生大量内存碎片.内存碎片过FullGC.因此CMS-pactAtFullCollection开关参数,用于在FullGC后再执行一个碎片整理过程.但内存整理是无法并发的,内存碎片问题虽然没有了,但停顿时间也因此变长了,因此CMS paction用于设置在执行N次不进行内存整理的FullGC后,跟着来一次带整理的(默认为0:每次进入FullGC时都进行碎片整理).分区收集G1G1(Garbage-First)是一款面向服务端应用的收集器,CPU的服务-G1isnnedasthelongtermrecementfortheConcurrentMark-SweepCollector-XX:+UseG1GCG1收集器与其他基于分代的收集器不同,G1将整个Java堆划分为多个大小相等的独立区域(Region),虽然还保留有和老年代的概念,但和老年代不再是物理的了,Region(不需要连续)的集合.如:OY区,因此不需要一次就对整个老年代/新生代回收.而是当线程并发寻找可回收的对象时,有些区块包含可回收的对象要比其他区块多很多.G1仍然需要暂停应用线程,但可以用相对较少的时间优先回收较多的Region.这种方式保证了G1可以在有限的时间内获取尽可能高的收集效率.G1的收集跟ParNew类似:存活的对象被转移到一个/多个SurvivorRegions.如果存活时间达到阀值,这部分对象就会被提升到老年代.如图:Survivor区或老年代heap区组成,这种方法使得可以动态调整各代区域尺寸.YoungGC会有STW,进行时所有应用程序线程都会被暂停.G1GC特点如下regionsSTW期间回收(whichregionswillbebesttoreclaimduringanevacuationpause).CMS有清理阶段.Snapshot-at-the-Beginning(SATB)CMS快得多region直接被回收拷贝/清理阶段(Copying/CleanupJVM优JDKJVM优化相关命HotspotVM数参数、主类名/JarHotspotVM运行看]、JIT编译命令格式:jstat-gc250查看和修改虚拟机各-flagheapdump:生成VMfinalizeJava VM当前时刻的线程快照:当前VM内每一条线程正在执行的方法堆JVM字节码代码自动解析.class文件,避免classclass一个多功能工具,以用来导出堆,查看Java等jmap、jstackJMX的可视化监CPU信息,以及对JMXMBean进JDK中最强大运行监可以内存垃jps-idjps-idJVMjstatid执行时间(单位毫秒)jstat-gc448830 0SXC-survivor初始空间大小,单位字节。SXUsurvivorEC-eden初始空间大小EUeden使用空间大小OC-old初始空间大小OU-old使用空间大小PCpermanent初始空间大小PUpermanent使用空间大小YGC-youngGC收集次数YGCTyoungGCFGCfullGCFGCTfullGCGCT-总计收集使用总时长JDKVMvisualgc插jvisualvmJVM常见参配置方式:java[options]MainClassoptionsJVM参数命名:常见为-参数名-参数名=参数值|-参数名:内存设-Xms:初始堆大小,JVM-Xmx:最大堆大小,JVM运行过程中,如果初始堆空间不足的时候,最大可以扩展到多般固定大小为64m,所以增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,Sun推荐配置为整个堆的3/8。-Xss:设置每个线程的Java栈大小。JDK5.0以后每个线程Java栈大小为1M,以前每个256K。根据应用的线程所需内存大小进行调整。在相同物理内存下,减小3000~5000左右。-XX:NewRatio=n:设置年轻代和年老代的比值。如:31:3,年轻代占整个年轻代+1/4-XX:SurvivorRatio=n:年轻代中Eden区与两个SurvivorSurvivor区有两个。如:3,表示Eden:Survivor=3:2Survivor1/5内存设置经验321.5G~2G;64为操作系统对内存。Tomcatcatalina.bat|catalina.shJAVA_OPTS参数设置。windowslinux配置方式不同。windows-set"JAVA_OPTS=%JAVA_OPTS%自定义参数";linux-JAVA_OPTS="$JAVA_OPTS自定义参数"-Xmx3550mXms3550mXmn2gXss128k-Xmx3550m-Xms3550m-Xss128k-XX:NewRatio=4-XX:SurvivorRatio=4-XX:MaxPermSize=160m-XX:MaxTenuringThreshold=0适合高并发本地测试使用。且大数据对象相对较多(IO流)40%(40%是生命周期较长的)-Xmx10G-Xms10G-Xss1M-XX:NewRatio=3-XX:SurvivorRatio=4-XX:MaxPermSize=2048m-收集器-XX:+UseSerialGC:-XX:+UseParallelOldGC:设置并行年老代收集器,JDK6.0的配置失效,原因不明。所以,此时年轻代大小最好用-Xmn-XX:+UseG1GC:G1回收统计信logc----并行收集器设

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论