配色: 字号:
Java知识汇总(游戏&后端)
2020-11-30 | 阅:  转:  |  分享 
  
游戏&后端2020-11-28演讲人01JVMJVM意义屏蔽各个硬件平台和操作系统的内存访问差异,以实现让Java程序在各种
平台下都能达到一致的内存访问效果工具参数实践垃圾收集器有关概念JVMABC垃圾回收算法方法区回收时机常见知识点DEF类加载机制Ja
va对象运行时数据区组成JVM编写高效优雅Java程序040603020501JVM工具mathttp://spotify.git
hub.io/threaddump-analyzer/jconsoleVisualVMGC分析arthasGC分析P6P5jhat
P4jstackP3jmapP2JstatP1GChistogcviewerJVM参数-Xss设置每个线程可使用的内存大小,即
栈的大小。在相同物理内存下,减小这个值能生成更多的线程,当然操作系统对一个进程内的线程数还是有限制的,不能无限生成。线程栈的大小是
个双刃剑,如果设置过小,可能会出现栈溢出,特别是在该线程内有递归、大的循环时出现溢出的可能性更大,如果该值设置过大,就有影响到创建
栈的数量,如果是多线程的应用,就会出现内存溢出的错误。-Xms初始堆大小-Xmx最大堆大小-Xmn新生代大小-XX:N
ewRatio:设置新生代和老年代的比值。如:为3,表示年轻代与老年代比值为1:3-XX:SurvivorRatio:新生代中Ed
en区与两个Survivor区的比值。注意Survivor区有两个。如:为3,表示Eden:Survivor=3:2,一个Surv
ivor区占整个新生代的1/5JVM参数0102-XX:MaxTenuringThreshold:设置转入老年代的存活次数。如果是
0,则直接跳过新生代进入老年代-XX:PermSize、-XX:MaxPermSize:分别设置永久代最小大小与最大大小(Java
8以前)0306-XX:+UseParalledlOldGC:设置并行老年代收集器-XX:MetaspaceSize、-XX:Ma
xMetaspaceSize:分别设置元空间最小大小与最大大小(Java8以后)0504-XX:+UseParallelGC:设置
并行收集器-XX:+UseSerialGC:设置串行收集器JVM参数-XX:+UseConcMarkSweepGC:设置并发收集器
-XX:+PrintGCDetails-Xloggc:filename-XX:+PrintGC-XX:+PrintGCTimeSt
amps-XX:ParallelGCThreads=n:设置并行收集器收集时使用的CPU数。并行收集线程数。JVM参数JVM实践0
1https://developer.ibm.com/zh/articles/j-lo-jvm-optimize-experien
ce/02https://www.javazhiyin.com/51851.html03例子JVM垃圾收集器0601ZGCSeri
al0502G1PraNew0403老年代收集器ParallelScavengeJVM垃圾收集器常见搭配总结Serial参数
控制:-XX:+UseSerialGC串行收集器新生代、老年代使用串行回收;垃圾收集的过程中会StopTheWorld(服
务暂停)0103050204串行收集器单线程新生代复制算法、老年代标记-压缩PraNew-XX:+UseParNewGCP
arNew收集器-XX:ParallelGCThreads限制线程数量Serial收集器的多线程版本,控制参数、收集算法、回收
策略等等和Serial收集器完全一样。ParallelScavengeParallelScavenge新生代复制算法
、老年代标记-压缩老年代收集器SerialOld一种是在JDK1.5及以前的版本中和ParallelScavenge收集器搭配
使用一个单线程的老年代版本收集器老年代收集器ParallelOldCAB参数控制:-XX:+UseParallelOldGC
使用Parallel收集器+老年代并行ParallelOld是ParallelScavenge收集器的老年代版本使用多线程和
“标记-整理”算法。CMSCMS(ConcurrentMarkSweep)收集器是一种以获取最短回收停顿时间为目标的收集器,它
非常符合那些集中在互联网站或者B/S系统的服务端上的Java应用,这些应用都非常重视服务的响应速度。从名字上(“MarkSwee
p”)就可以看出它是基于“标记-清除”算法实现的。针对老年代的回收步骤整个过程中耗时最长的并发标记和并发清除过程收集器线程都可以与
用户线程一起工作优点缺点CMS相关参数CMS步骤初始标记(CMSinitialmark):仅仅只是标记一下GCRoots能直
接关联到的对象,速度很快,需要“StopTheWorld”。并发标记(CMSconcurrentmark):进行GCRo
otsTracing的过程,在整个过程中耗时最长。重新标记(CMSremark):为了修正并发标记期间因用户程序继续运作而导致
标记产生变动的那一部分对象的标记记录,这个阶段的停顿时间一般会比初始标记阶段稍长一些,但远比并发标记的时间短。此阶段也需要“Sto
pTheWorld”。并发清除(CMSconcurrentsweep)CMS优点并发收集、低停顿,因此CMS收集器也被称为
并发低停顿收集器(ConcurrentLowPauseCollector)。CMS缺点对CPU资源非常敏感其实,面向并发设
计的程序都对CPU资源比较敏感。在并发阶段,它虽然不会导致用户线程停顿,但会因为占用了一部分线程(或者说CPU资源)而导致应用程序
变慢,总吞吐量会降低。CMS默认启动的回收线程数是(CPU数量+3)/4,也就是当CPU在4个以上时,并发回收时垃圾收集线程不少于
25%的CPU资源,并且随着CPU数量的增加而下降。但是当CPU不足4个时(比如2个),CMS对用户程序的影响就可能变得很大,如果
本来CPU负载就比较大,还要分出一半的运算能力去执行收集器线程,就可能导致用户程序的执行速度忽然降低了50%,其实也让人无法接受。
CMS缺点无法处理浮动垃圾(FloatingGarbage)可能出现“ConcurrentModeFailure”失败而导
致另一次FullGC的产生。由于CMS并发清理阶段用户线程还在运行着,伴随程序运行自然就还会有新的垃圾不断产生。这一部分垃圾出现
在标记过程之后,CMS无法再当次收集中处理掉它们,只好留待下一次GC时再清理掉。这一部分垃圾就被称为“浮动垃圾”。也是由于在垃圾收
集阶段用户线程还需要运行,那也就还需要预留有足够的内存空间给用户线程使用,因此CMS收集器不能像其他收集器那样等到老年代几乎完全被
填满了再进行收集,需要预留一部分空间提供并发收集时的程序运作使用。CMS缺点标记-清除算法导致的空间碎片CMS是一款基于“标记-
清除”算法实现的收集器,这意味着收集结束时会有大量空间碎片产生。空间碎片过多时,将会给大对象分配带来很大麻烦,往往出现老年代空间剩
余,但无法找到足够大连续空间来分配当前对象。CMS缺点如果对象分配率高于CMS回收的效率,将导致在CMS完成之前老年代就被填满,这
种状况成为“并发模式失败”,同样也会引起fullGC。可以调节-XX:CMSInitiatingOccupancyFractio
n和新生代的堆大小。CMS相关参数-XX:+UseConcMarkSweepGC-启用CMS,同时-XX:+UseParNew
GC会被自动打开。-XX:CMSInitiatingOccupancyFraction-设置第一次启动CMS的阈值,默认是68
%。-XX:+UseCMSInitiatingOccupancyOnly-只是用设定的回收阈值,如果不指定,JVM仅在第一次使
用设定值,后续则自动调整。-XX:+CMSPermGenSweepingEnabled-回收perm区。-XX:+CMSCla
ssUnloadingEnabled-相对于并行收集器,CMS收集器默认不会对永久代进行垃圾回收(在1.7中是默认关闭,但是在
1.8中是默认打开的)。如果希望对永久代进行垃圾回收,则可以打开此标志,同时打开-XX:+CMSPermGenSweepingEn
abled92%默认值。CMS相关参数-XX:+CMSConcurrentMTEnabled-并发的CMS阶段将会启动多个
GC线程和其他线程并发工作,默认为true。CMS相关参数-XX:+UseCMSCompactAtFullCollection-
在fullGC的时候进行整理(marksweepcompact),默认为true。CMS相关参数-XX:+CMSFullG
CsBeforeCompaction-在上一次CMS并发GC执行过后,到底还要再执行多少次fullGC(注意不是CM
SGC)才会做压缩,默认是0。如果增大这个参数,会使fullGC更少做压缩,但也就更容易使CMS的老年代受碎片化问题的困扰。
本来这个参数就是用来配置降低fullGC压缩的频率,以期减少某些fullGC的暂停时间。CMS回退到fullGC时用的算法是
mark-sweep-compact,但compaction是可选的,不做的话碎片化会严重些但这次fullGC的暂停时间会短些,
这是个取舍。CMS相关参数-XX:+CMSParallelRemarkEnabled-并行remark,以减少remark的等
待时间。默认为true。CMS相关参数-XX:+CMSScavengeBeforeRemark-强制remark之前开始一次m
inorGC,可以减少remark的等待时间,因为老生代的对象有的会依赖于新生代的对象,当增加了这个命令时会在remark之前执
行一次minorGC的操作,从而可以减少老生代到新生代的可到达对象数。默认为false。G1设计初衷是为了尽量缩短处理超大堆时产
生的停顿。在回收的时候将对象从一个小堆区复制到另一个小堆区,这意味着G1在回收垃圾的时候同时完成了堆的部分内存压缩,相对于CMS的
优势而言就是内存碎片的产生率大大降低。横跨整个堆内存上一代的垃圾收集器一样在逻辑上被划分Eden、Survivor和老年代,但是各
种角色的region个数都不是固定的。它将整个Java堆划分为多个大小相等的独立区域(Region),虽然还保留新生代和老年代的概
念,但新生代和老年代不再是物理隔离的了,而都是一部分Region(不需要连续)的集合。特征步骤图例G1参数总结G1特征并行与并发
G1能充分利用多CPU、多核环境下的硬件优势,使用多个CPU来缩短“StopTheWorld”停顿时间,部分其他收集器原本需
要停顿Java线程执行的GC动作,G1收集器仍然可以通过并发的方式让Java程序继续执行。分代收集与其他收集器一样,分代概念在G
1中依然得以保留。虽然G1可以不需要其他收集器配合就能独立管理整个GC堆,但它能够采用不同方式去处理新创建的对象和已存活一段时间、
熬过多次GC的旧对象来获取更好的收集效果。空间整合G1从整体来看是基于“标记-整理”算法实现的收集器,从局部(两个Region之
间)上来看是基于“复制”算法实现的。这意味着G1运行期间不会产生内存空间碎片,收集后能提供规整的可用内存。此特性有利于程序长时间运
行,分配大对象时不会因为无法找到连续内存空间而提前触发下一次GC。G1特征可预测的停顿这是G1相对CMS的一大优势,降低停顿时间
是G1和CMS共同的关注点,但G1除了降低停顿外,还能建立可预测的停顿时间模型,能让使用者明确指定在一个长度为M毫秒的时间片段内,
消耗在GC上的时间不得超过N毫秒,这几乎已经是实时Java(RTSJ)的垃圾收集器的特征了G1步骤初始标记(InitialMar
king)仅仅只是标记一下GCRoots能直接关联到的对象,并且修改TAMS(NestTopMarkStart)的值,
让下一阶段用户程序并发运行时,能在正确可以的Region中创建对象,此阶段需要停顿线程,但耗时很短。STW(stop-th
e-world)并发标记(ConcurrentMarking)从GCRoot开始对堆中对象进行可达性分析,找到存活对象,此
阶段耗时较长,但可与用户程序并发执行。G1步骤最终标记(FinalMarking重新标记阶段)为了修正在并发标记期间因用户
程序继续运作而导致标记产生变动的那一部分标记记录,虚拟机将这段时间对象变化记录在线程的RememberedSetLogs里面,
最终标记阶段需要把RememberedSetLogs的数据合并到RememberedSet中,这阶段需要停顿线程,但是可并行
执行。STW(stop-the-world)筛选回收(LiveDataCountingandEvacuation复
制/清除阶段)首先对各个Region中的回收价值和成本进行排序,根据用户所期望的GC停顿是时间来制定回收计划。此阶段其实也可以
做到与用户程序一起并发执行,但是因为只回收一部分Region,时间是用户可控制的,而且停顿用户线程将大幅度提高收集效率。STW
(stop-the-world)G1参数01-XX:+UseG1GC启用G1垃圾收集器02-XX:MaxGCPauseMilli
s=n指定期望的最大停顿时间,有大概率保证在该范围内,但并非一定能实现。ms03-XX:G1HeapRegionSize=n
设置的G1区域的大小。值是2的幂,范围是1MB到32MB之间。目标是根据最小的Java堆大小划分出约2
048个区域。04-XX:ParallelGCThreads=n设置STW工作线程数的值。将n的值设置为逻辑处理器的数
量。n的值与逻辑处理器的数量相同,最多为8。如果逻辑处理器不止八个,则将n的值设置为逻辑处理器数的5/8左右。这适用于
大多数情况,除非是较大的SPARC系统,其中n的值可以是逻辑处理器数的5/16左右。G1参数01-XX:ConcGCT
hreads=n设置并行标记的线程数。将n设置为并行垃圾回收线程数(ParallelGCThreads)的1/4左右
。02-XX:InitiatingHeapOccupancyPercent=45设置触发标记周期的Java堆占用率阈值。默认
占用率是整个Java堆的45%。03-XX:G1ReservePercent=n设置堆内存保留为假天花板的总量,以降低提升
失败的可能性,默认值是10。04不要设置年轻代大小通过-Xmn明确地设置年轻代大小来插手G1收集器的默认行为。收集时G1收
集器将不再遵照暂停时间指标。所以本质上,设置年轻代大小将不会启用暂停时间目标。G1收集器将不能按需扩张、收缩年轻代空间。自从大
小被固定之后,大小将不再会被改变。ZGC环境:JDK11中推出的一款低延迟垃圾回收器ZGC设计目标停顿时间不超过10ms;停
顿时间不会随着堆的大小,或者活跃对象的大小而增加;支持8MB~4TB级别的堆(未来支持16TB)。很多低延迟高可用Java服务的系
统可用性经常受GC停顿的困扰。GC停顿指垃圾回收期间STW(StopTheWorld),当STW时,所有应用线程停止活动,等待
GC停顿结束。CMS新生代的YoungGC、G1和ZGC都基于标记-整理算法ZGC解决痛点G1复制算法中的转移阶段需要分配
新内存和复制对象的成员变量。转移阶段是STW的,其中内存分配通常耗时非常短,但对象成员变量的复制耗时有可能较长,这是因为复制耗时与
存活对象数量与对象复杂度成正比。对象越复杂,复制耗时越长。G1未能解决转移过程中准确定位对象地址的问题。ZGC在标记、转移和重定位
阶段几乎都是并发的,这是ZGC实现停顿时间小于10ms目标的最关键原因。ZGC原理ZGC只有三个STW阶段:初始标记,再标记,初始
转移。其中,初始标记和初始转移分别都只需要扫描所有GCRoots,其处理时间和GCRoots的数量成正比,一般情况耗时非常短;
再标记阶段STW时间很短,最多1ms,超过1ms则再次进入并发标记阶段。ZGC几乎所有暂停都只依赖于GCRoots集合大小,停顿
时间不会随着堆的大小或者活跃对象的大小而增加。与ZGC对比,G1的转移阶段完全STW的,且停顿时间随存活对象的大小增加而增加。关键
技术色指针JVM是如何判断对象被移动过呢?就是利用对象引用的地址,即着色指针。着色指针是一种将信息存储在指针中的技术。ZGC实际
仅使用64位地址空间的第0~41位,而第42~45位存储元数据,第47~63位固定为0。读屏障技术解决了转移过程中准确访问对象的
问题,实现了并发转移。大致原理描述如下:并发转移中“并发”意味着GC线程在转移对象的过程中,应用线程也在不停地访问对象。假设对象发
生转移,但对象地址未及时更新,那么应用线程可能访问到旧地址,从而造成错误。而在ZGC中,应用线程访问对象将触发“读屏障”,如果发现
对象被移动了,那么“读屏障”会把读出来的指针更新到对象的新地址上,这样应用线程始终访问的都是对象的新地址。读屏障是JVM向应用代码
插入一小段代码的技术。当应用线程从堆中读取对象引用时,就会执行这段代码。需要注意的是,仅“从堆中读取对象引用”才会触发这段代码。子
主题ZGC效果图注意事项参数样例注意事项ZGC触发时机注意事项ZGC日志ZGC停顿原因ZGC调优实践JVM有关概念并行
和并发延迟是应用程序响应度的表现,垃圾收集暂停会影响应用程序的响应性。MinorGC和FullGC0305010204
吞吐量空间量是进程的工作集,以页和缓存线为衡量。在具有有限物理内存或者多处理器的系统上,空间量可能可伸缩。Promptnes
s是对象死亡到内存可用之间的时间,这是分布式系统的一个重要考量因素,包括RMI。并行和并发No.1并行(Parallel):指多条
垃圾收集线程并行工作,但此时用户线程仍然处于等待状态。No.2并发(Concurrent):指用户线程与垃圾收集线程同时执行(但不
一定是并行的,可能会交替执行),用户程序在继续运行。而垃圾收集程序运行在另一个CPU上。吞吐量吞吐量就是CPU用于运行用户代码的时
间与CPU总消耗时间的比值,即吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间)。假设虚拟机总共运行了
100分钟,其中垃圾收集花掉1分钟,那吞吐量就是99%。吞吐量是长时间内未使用于垃圾收集的总时间的百分比。吞吐量包含分配内存所
花费的时间(不过通常不需要调整分配的速度)。MinorGC和FullGC新生代GC(MinorGC):指发生在新生代的
垃圾收集动作,因为Java对象大多都具备朝生夕灭的特性,所以MinorGC非常频繁,一般回收速度也比较快。老年代GC(Major
GC/FullGC):指发生在老年代的GC,出现了MajorGC,经常会伴随至少一次的MinorGC(但非绝对的,在P
arallelScavenge收集器的收集策略里就有直接进行MajorGC的策略选择过程)。MajorGC的速度一般会比Mi
norGC慢10倍以上。JVM垃圾回收算法引用计数算法可达性分析算法复制算法标记-清除算法标记-整理算法分代收集算法JVM垃圾回
收算法HotSpot算法引用计数算法01引用计数是垃圾收集器中的早期策略。在这种方法中,堆中每个对象实例都有一个引用计数。当一个对
象被创建时,就将该对象实例分配给一个变量,该变量计数设置为1。当任何其它变量被赋值为这个对象的引用时,计数加1(a=b,则b引
用的对象实例的计数器+1),但当一个对象实例的某个引用超过了生命周期或者被设置为一个新值时,对象实例的引用计数器减1。任何引用计数
器为0的对象实例可以被当作垃圾收集。当一个对象实例被垃圾收集时,它引用的任何对象实例的引用计数器减1。02优点:引用计数收集器可以
很快的执行,交织在程序运行中。对程序需要不被长时间打断的实时环境比较有利。缺点:无法检测出循环引用。如父对象有一个对子对象的引
用,子对象反过来引用父对象。这样,他们的引用计数永远不可能为0。可达性分析算法从一个节点GCROOT开始,寻找对应的引用节点,找
到这个节点以后,继续寻找这个节点的引用节点,当所有的引用节点寻找完毕之后,剩余的节点则被认为是没有被引用到的节点,即无用的节点,无
用的节点将会被判定为是可回收的对象。作为GCRoots的对象虚拟机栈中引用的对象(栈帧中的本地变量表);方法区中类静态属性引用
的对象;方法区中常量引用的对象;本地方法栈中JNI(Native方法)引用的对象。复制算法010102它将可用内存按容量划分为大小
相等的两块,每次只使用其中的一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用的内存空间一次清理掉,
这样一来就不容易出现内存碎片的问题。高昂的代价,因为能够使用的内存缩减到原来的一半。标记-清除算法12标记-清除算法分为两个阶段:
标记阶段和清除阶段。标记阶段的任务是标记出所有需要被回收的对象,清除阶段就是回收被标记的对象所占用的空间。会造成内存碎片为了解决C
opying算法的缺陷,充分利用内存空间,提出了Mark-Compact算法。该算法标记阶段和Mark-Sweep一样,但是在完成
标记之后,它不是直接清理可回收对象,而是将存活对象都向一端移标记-整理算法采用标记-清除算法一样的方式进行对象的标记,但在清除时
不同,在回收不存活的对象占用的空间后,会将所有的存活对象往左端空闲空间移动,并更新对应的指针。标记-整理算法是在标记-清除算法的基
础三个阶段标记阶段,即从GCRoots集合开始,标记活跃对象;转移阶段,即把活跃对象复制到新的内存地址上;重定位阶段,因为转
移导致对象的地址发生了变化,在重定位阶段,所有指向对象旧地址的指针都要调整到对象新的地址上。标记-整理算法分代收集算法它的核心思想
是根据对象存活的生命周期将内存划分为若干个不同的区域。一般情况下将堆区划分为老年代(TenuredGeneration)和新生代
(YoungGeneration),在堆区之外还有一个代就是永久代(PermanetGeneration)。老年代的特点是每次
垃圾收集时只有少量对象需要被回收,而新生代的特点是每次垃圾回收时都有大量的对象需要被回收,那么就可以根据不同代的特点采取最适合的收
集算法。HotSpot算法枚举根结点当执行系统停顿下来后,并不需要一个不漏的检查完所在执行上下文和全局的引用位置,在HotSpot
的实现中,使用一组称为OopMap的数据结构来存放对象引用安全点在这些特定的位置,线程的状态可以被确定位置方法调用指令循环跳
转指令异常跳转指令中断方式抢占式主动式HotSpot算法安全区域成功背景:线程Sleep状态或者Blocked状态的时候,无法响应
JVM中断,走到安全的地方,JVM也不能等他们,这样就无法进行GC安全区域是指在一段代码中,引用关系不会发生变化,这个区域中的任何
地方开始GC都是安全的。JVM方法区回收时机该类所有的实例都已经被回收,也就是Java堆中不存在该类的任何实例;加载该类的Clas
sLoader已经被回收;该类对应的java.lang.Class对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。
040603020501JVM常见知识点-verbose:gc打印关于每次收集堆和垃圾收集的信息。作为GCRoots的对象包
括4种情况JVM的内存结构新生代和老年代的区别GC是什么时候触发的并行垃圾收集器ParallelGC作为GCRoots的对
象包括4种情况方法区中类静态属性引用的对象;01虚拟机栈中引用的对象(栈帧中的本地变量表);方法区中常量引用的对象;0203本地方
法栈中JNI(Native方法)引用的对象。04JVM的内存结构12随线程而生、随线程而灭堆区程序计数器虚拟机栈本地方法栈3方法
区新生代和老年代的区别所谓的新生代和老年代是针对于分代收集算法来定义的,新生代又分为Eden和Survivor两个区。加上老年代
就这三个区。数据会首先分配到Eden区当中(当然也有特殊情况,如果是大对象那么会直接放入到老年代(大对象是指需要大量连续内存空间
的java对象)。),当Eden没有足够空间的时候就会触发jvm发起一次MinorGC。如果对象经过一次MinorGC还存活
,并且又能被Survivor空间接受,那么将被移动到Survivor空间当中。并将其年龄设为1,对象在Survivor每熬过一次
MinorGC,年龄就加1,当年龄达到一定的程度(默认为15)时,就会被晋升到老年代中了,当然晋升老年代的年龄是可以设置的。如
果老年代满了就执行:FullGC因为不经常执行,因此采用了Mark-Compact算法清理ScavengeGC一般情况下
,当新对象生成,并且在Eden申请空间失败时,就会触发ScavengeGC,对Eden区域进行GC,清除非存活对象,并且把尚且存
活的对象移动到Survivor区。然后整理Survivor的两个区。这种方式的GC是对年轻代的Eden区进行,不会影响到年老代。因
为大部分对象都是从Eden区开始的,同时Eden区不会分配的很大,所以Eden区的GC会频繁进行。因而,一般在这里需要使用速度快、
效率高的算法,使Eden去能尽快空闲出来。GC是什么时候触发的FullGC年老代(Tenured)被写满;持久代(Perm)被
写满;System.gc()被显示调用;上一次GC之后Heap的各域分配策略动态变化并行垃圾收集器ParallelGC串行和
并行垃圾收集器之间的主要区别在于并行垃圾收集器使用多线程去加快垃圾收集速度。并行垃圾收集器ParallelGC使用命令行选项
-XX:+UseParallelGC启用并行垃圾收集器。默认情况下,使用该选项,minor和major垃圾收集都并行运行,以进一步
减少垃圾收集开销。最大垃圾收集暂停时间:最大垃圾收集暂停时间目标用命令行选项-XX:MaxGCPauseMillis=<N&
gt;指定。这被解释为一个提示,期望暂停时间是<N>毫秒或者更小的时间。默认情况下,没有最大暂停时间目标。如果指定了暂
停时间目标,则会调整堆大小和与垃圾收集相关的其他参数,以使垃圾收集暂停时间小于指定值。但是,可能并不总是满足所需的暂停时间目标。这
些调整可能会导致垃圾收集器降低应用程序的总吞吐量。并行垃圾收集器ParallelGC允许指定行为,而不是指定分代堆的大小和其
他低级别的调优细节。吞吐量:吞吐量目标是根据进行垃圾收集所花费的时间与在垃圾收集外所花费的时间(称为应用程序时间)来衡量的。目标由
命令行选项-XX:GCTimeRatio=<N>指定,该选项将垃圾收集时间与应用程序时间的比率设置为1/(1+N)
。并行垃圾收集器ParallelGC允许指定行为,而不是指定分代堆的大小和其他低级别的调优细节。空间量(堆大小)用选项-
Xmx<N>来指定最大堆大小。另外,垃圾收集器有一个隐藏的目标,即只要满足其他目标,就可以最小化堆的大小。(能力守恒)
并行垃圾收集器ParallelGC使用线程数的计算-XX:ParallelGCThreads=<N>来控制
在具有<N>个硬件线程并且<N>大于8的机器上,并行垃圾收集器使用<N>固定的分数作为垃圾收
集器的线程。对于较大的<N>值,这个分数约为5/8。当<N>值比8小的时候,使用的分数即为<N&
gt;。在选定的平台上,分数下降到5/16。并行垃圾收集器ParallelGC减少垃圾收集线程的数量并增大年老代的大小将减少
此碎片效应并行垃圾收集器ParallelGC并行垃圾收集器目标的优先级成功目标按如下顺序处理:最大暂停时间,吞吐量和最小堆大
小目标。首先满足最大暂停时间目标,只有在达到这个目标之后,吞吐量目标才得以实现。相似地,只有在前两个目标实现之后,才会考虑足迹目标
。并行垃圾收集器分代堆大小调整垃圾收集器保留的统计信息(如平均暂停时间)将在每次垃圾收集结束时更新。调用System.gc()会忽
略保留统计信息和调整分代堆大小。分代堆大小的固定百分比来增量增长或者缩小分代堆大小的,以便分代可以增加或者减少到他期待的堆大小
。增长和缩小分代堆大小是根据不同的速率进行的。默认情况下,增长以20%的增量增长,收缩以5%的增量收缩。使用年轻代命令行-XX:
YoungGenerationSizeIncrement=<Y>和年老代命令行-XX:TenuredGeneratio
nSizeIncrement。分代收缩的百分比由命令行标识-XX:AdaptiveSizeDecrementScaleFactor
=<D>。如果增长率是X%,则收缩率为X/D%。并行垃圾收集器ParallelGC并行垃圾收集器默认堆大小123
可以使用选项-Xms(初始堆大小)和-Xmx(最大堆大小)来指定初始堆和最大堆大小。如果知道应用程序需要多少堆才能正常工作,那么将
-Xms和-Xmx设置为相同的值。如果不知道,那么JVM将首先使用初始化堆大小,然后逐步增加Java堆大小直到在堆使用和性能之间找
到平衡。其他的参数和选项会影响这些默认值。要验证默认值,请使用-XX:+PrintFlagsFinal选项并且在输出中查找-XX:
MaxHeapSize。JVM类加载机制类加载器负责读取Java字节代码,并转换成java.lang.Class类的一个实
例01类加载器除了用于加载类外,还可用于确定类在Java虚拟机中的唯一性。即便是同样的字节代码,被不同的类加载器加载之后所得到的类,也是不同的。02种类03双亲委派模型04种类自定义类加载器,通过继承ClassLoader实现,一般是加载我们的自定义类DC应用程序类加载器,ApplicationClassLoader,加载ClassPath中的类库B扩展类加载器,ExtensionClassLoader,加载\\lib\\ext,或者被java.ext.dirs系统变量指定的类A启动类加载器,BootstrapClassLoader,加载JACA_HOME\\lib,或者被-Xbootclasspath参数限定的类双亲委派模型双亲委派是指每次收到类加载请求时,先将请求委派给父类加载器完成(所有加载请求最终会委派到顶层的BootstrapClassLoader加载器中),如果父类加载器无法完成这个加载(该加载器的搜索范围中类加载过程加载,连接,初始化;优点避免同一个类被多次加载;每个加载器只能加载自己范围内的类;问题JVMJava对象对象的创建对象创建流程图对象的访问定位垃圾对象的判定ABCD对象的创建1、检查参数是否在常量池中定位到一个类的符号引用;该类是否被加载、解析、初始化过若没有做进行类加载2、若有则分配内存内存不规整线程安全内存绝对规整用“空闲列表”来分配内存用“指针碰撞”来分配内存对象的创建3、始化已分配内存为零值(保证类型不赋初值可以使用)对象的创建4、上面工作完成后,执行init方法按照程序员意愿初始化对象对象的创建对象的内存布局02JavaJava03JDBCJDBC04MybatisMybatis05shiroshiro06SpringSpring07SpringCloudSpringCloud08Serverlet容器Serverlet容器09ProtobufProtobuf10算法与数据结构算法与数据结构11设计模式设计模式12数据库数据库13网络网络14运维运维15分布式场景分布式场景16压力测试压力测试17团队协作团队协作18安全安全感谢聆听
献花(0)
+1
(本文系职场细细品原创)