不奢望岁月静好 只希望点滴积累

0%

下载分词器jar包

1
2
百度网盘地址:
链接:https://pan.baidu.com/s/1GHwv6uBcUhI7GpOpqFnl4g 密码:121w

使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
1. 将压缩包解压、重命名为ik_analyzer
2. 将 ik-analyzer-solr6.jar 复制到 solr lib目录下
cp ~/Downloads/ik_analyzer/ik-analyzer-solr6.jar ~/www/Java/solr/WEB-INF/lib
3. 将相关包放入solr classpath
cp ~/Downloads/ik_analyzer/mydict.dic ~/Downloads/ik_analyzer/IKAnalyzer.cfg.xml ~/Downloads/ik_analyzer/ext_stopword.dic ~/www/Java/solr/WEB-INF/classes
若~/www/Java/solr/WEB-INF/classes文件夹不存在、需要新建
4. 配置schema

<!-- IKAnalyzer-->
<fieldType name="text_ik" class="solr.TextField">
<analyzer class="org.wltea.analyzer.lucene.IKAnalyzer"/>
</fieldType>

<field name="item_title" type="text_ik" indexed="true" stored="true"/>
<field name="item_sell_point" type="text_ik" indexed="true" stored="true"/>
<field name="item_price" type="plong" indexed="true" stored="true"/>
<field name="item_image" type="string" indexed="false" stored="true" />
<field name="item_category_name" type="string" indexed="true" stored="true" />

<field name="item_keywords" type="text_ik" indexed="true" stored="false" multiValued="true"/>
<copyField source="item_title" dest="item_keywords"/>
<copyField source="item_sell_point" dest="item_keywords"/>
<copyField source="item_category_name" dest="item_keywords"/>

其中:copyfiled是将item_title、item_sell_point、item_category_name都作为后边的item_keywords来搜索

5. 保存、重启tomcat、访问页面
http://localhost:8081/solr/index.html

analyzer.png

问题

1
2
3
4
如果遇到错误:java.lang.AbstractMethodError
可以检查下分词器的版本是否过低
当前这篇文章使用的solr是7.2.1的版本、使用的是网盘保存的分词器版本、是ok的、
之前使用了 IKAnalyzer2012FF_u1.jar 这个版本、出现的上述错误~

error.png

G1收集器

上篇文章简单介绍了七种垃圾回收器、既然G1是最前沿的、有必要补充说明一下:
1. 横跨整个堆内存: 在G1之前的其它收集器收集范围都是整个新生代或者老年代
G1在使用时、将整个Java堆划分为多个大小相等的独立区域(Region)
保留新生代和老年代的概念、但不再物理隔离、都是一部分Region(不需要连续)的集合
2. 建立可预测的时间模型: G1跟踪各个Region里垃圾堆积的价值大小(回收可获得空间大小及回收所需时间的经验值)
在后台维护一个优先级列表, 每次根据允许的收集时间、优先回收价值最大的Region(Garbage First)
这种实验Region划分内存空间及有优先级的区域回收方式、保证了G1在有限时间内的收集效率
3. 避免全堆扫描: G1将堆分为多个Region、就是化整为零、单Region不可能是孤立的、一个对象分配在某个Region中
可能与整个Java堆任意的对象发生引用关系、在做可达性分析确定对象是否存活时、需要扫整个Java堆保证准确性
严重损耗GC效率,
注意:
为了避免全堆扫描、虚拟机为每个Region维护了一个对应的Remembered Set、虚拟机发现程序对在Reference类型的
数据进行写操作时、会产生一个Writer Barrier暂时中断写操作、检测Reference引用的对象是否在不同的Region中
(在分代的例子中就是检测老年代对象是否引用了新生代对象)、若是则通过CardTable把相关引用记录到被引用对象所属的
Region的Remembered Set中、垃圾回收时,在GC根节点的枚举范围内加入Remembered Set即可保证不用全堆扫描也能不遗漏

1
2
3
4
5
6
7
8
9
10
11
12
13
14
若不计算维护Remembered Set的操作、G1大致步骤为:
1) 初始标记:initial mark仅标记GC Roots能直接关联的对象、并且修改TAMS(Nest top mark start)的值
让下阶段用户程序并发运行时、可在正确可以的Region中创建对象、此阶段需要停顿用户线程、但时间较短

2) 并发标记: concurrent Marking 从GC Root开始对堆中对象做可达性分析、找到存活对象
耗时较长、但可与用户线程`并发执行`

3) 最终标记: Final Marking 为了修正标记期间因用户程序继续运行导致标记产生变化的对象、
虚拟机将这段时间内对象变化记录在线程的`Remembered Set Logs`里、最终标记阶段需要将这部分数据合并
到 Remembered Set 中、需要`停顿线程`、但可`并行执行`

4) 筛选回收: Live Data and Evacuation 先对各个Region中的回收价值和成本进行排序
根据用户所期望的GC停顿时间来定制回收计划、此阶段也`可以`做到与用户线程`并发执行`、但因为只回收
一部分Region、且时间是用户可控制的、`停顿用户线程`将大幅度`提高收集效率`
G1适用分析
场景Scense:
   1. 多核多CPU而且大内存
   2. 要求低停顿

如何实现-XX:MaxGCPauseMillis所设置的目标?
   1. 对于新生代来说,G1自动调整新生代的大小
   2. 对于老年代来说,每次Mixed Garbage Collecttion的时候回收的Rigion个数会基于
      Mixed Garbage Collection的目标次数,每个Region中的存活对象百分比,以及堆全局的垃圾比例来设定
疑问
如何实现避免碎片?
   无论是新生代还是老年代,使用复制算法(将一批Region复制到另外一批Region中)

如何避免可达性分析扫描整个堆?
   每一个Region都有自己的RSets(Remembered Set) 用来记录对自己Region内对象的引用

在什么时机进行Mixed Garbage Collection?
   在堆的使用率达到-XX:InitiatingHeapOccupancyPercent所设置的使用率(老年代使用的内存/整个堆内存)时

   判断的时机是? 每次Young GC结束的时候

   因为老年代空间中的使用内存发生变化只有一个情形:Young GC的时候

G1的哪些过程需要STW?
   1) young gc: 采用的是复制算法 - 会STW、多线程进行
   2) mixed gc: 也是复制算法、mixed gc也包括对新生代的收集
   3) global concurrent mark中的initial mark、remark、部分clean up

既然有CMS,为什么要选择G1?
   1. STW更加可控
   2. 由于采用了标记-整理算法,不会产生内存碎片

Humongous Objects的分配和回收:
   1. 怎么算?大于Region的空间的一半的算Humongous Objects
   2. 放哪里?Humongous Objects被分配在Humongous Region,直接在老年代
   3. 回收:不在mixed gc,而在 global concurrent marking的最后一步:clean up中

可达性分析:
   找一组对象作为GC Root(根结点),并从根结点进行遍历,遍历结束后如果发现某个对象是不可达的,
   那么它就会被标记为不可达对象,等待GC

哪些对象可以作为GC Root
    能作为GC Root的对象必定为可以存活的对象,
    eg. 全局性的引用(静态变量和常量)以及某些方法的局部变量(栈帧中的本地变量表)

    以下对象通常可以作为GC Root:
    1) 存活的线程
    2) 虚拟机栈(栈桢中的本地变量表)中的引用的对象
    3) 方法区中的类静态属性以及常量引用的对象
    4) 本地方法栈中JNI引用的局部变量以及全局变量
G1调优
1
2
3
4
5
6
7
1. -XX:MaxGCPauseMillis
最大STW时间、参数设置过小会频繁GC、设置过大、吞吐量会降低、所以要合理的设置来保证
`最大停顿时间`和`最大吞吐量`的平衡
2. -XX:InitiatingHeapOccupancyPercent & -XX:+G1UseAdaptiveHop
InitiatingHeapOccupancyPercent简称IHOP
-XX:+G1UseAdaptiveIHOP是默认值,也就是说IHOPadaptive
-XX:InitiatingHeapOccupancyPercent是初始值
存在的问题
1. 跟cms一样、无法避免浮动垃圾的产生和溢出
    可以增加堆大小、或者GC线程`-XX:ConcGCThreads`来尽量避免
2. 同样存在晋升失败的问题
    可以提升`-XX:G1ReservePercent`同时同比例的增加堆大小、
    或者提前启动标记周期(减少-XX:InitiatingHeapOccupancyPercent)
GC 收集器总结:
收集器 串行、并行or并发 新生代/老年代 算法 目标 适用场景
Serial 串行 新生代 复制算法 响应速度优先 单CPU环境下的Client模式
Serial Old 串行 老年代 标记-整理 响应速度优先 单CPU环境下的Client模式、CMS的后备预案
ParNew 并行 新生代 复制算法 响应速度优先 多CPU环境时在Server模式下与CMS配合
Parallel Scavenge 并行 新生代 复制算法 吞吐量优先 在后台运算而不需要太多交互的任务
Parallel Old 并行 老年代 标记-整理 吞吐量优先 在后台运算而不需要太多交互的任务
CMS 并发 老年代 标记-清除 响应速度优先 集中在互联网站或B/S系统服务端上的Java应用
G1 并发 both 标记-整理+复制算法 响应速度优先 面向服务端应用,将来替换CMS
附:
1. `可达性`: GC Root可以到达此对象
2. `并行执行`: 多个线程同时执行gc
3. `并发执行`: 用户线程和GC线程同时执行

G1.png

JDK监控工具

jps: JVM Process Status Tool. 显示指定系统内所有HotSpot vm 进程
jstat: JVM statistic Monitor Tool. 用于收集vm各方面的运行数据
jinfo: Configuration Info For Java. 显示虚拟机配置信息
jmap: Memory Map For Java. 生成内存转储快照文件(headdump文件)
jhat: JVM Head Dump Browser. 用于分析dump文件、
jstack: 显示虚拟机的线程快照

jps

usage: jps [opt] [hostid]

-q 只输出LVMID 省略主类的名称
-m 输出虚拟机的进程启动时传递给主类函数的参数
-l 输出主类的全名、若主类注销的是jar包、输出jar包路径
-v 输出虚拟机启动时的jvm参数

jstat

usage: jstat [opt vmid [interval][s|ms] [count]]

-class 监视类装载、卸载数量、总空间及类装载所需时间
-gc 监视Java堆情况、包括Eden区、两个Survivor区、老年代、永久代的容量、已用空间、GC时间合计等信息
-gccapacity 监视内容与-gc基本相同、主要关注java堆各个区域用到的最大、最小空间
-gcutil 监视内容与-gc基本相同、主要关注已使用空间与总空间的比率
-gccause-gcutil相同、会额外输出导致上次gc的原因
-gcnew 监视新生代gc的状况
-gcnewcapacitygcnew基本相同、输出主要关注最大、最小空间
-gcold 监视老年代gc的状况
-gcoldcapacitygcold基本相同、输出主要关注最大、最小空间
-gcpermcapacity 输出永久代最大、最小空间
-compiler 输出jit编译过的方法、耗时等信息
-printcompalition 输出已被编译过的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
eg. jstat -gcutil  41610 250 3
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0.00 0.00 4.00 0.43 62.81 65.59 1 0.002 1 0.006 0.008
0.00 0.00 4.00 0.43 62.81 65.59 1 0.002 1 0.006 0.008
0.00 0.00 4.00 0.43 62.81 65.59 1 0.002 1 0.006 0.008
S0: survivor0区、都是空的
S1: survivor0区、都是空的
E: Eden区、4%的使用率
O: Old区、0.43%的使用率
M:Perm区、62.81%的使用率
CCS: class Space、 65.59%的使用率
YGC: young gc、1次
YGCT: young gc 耗时 0.002s
FGC: full gc 1
FGCT: full gc 耗时 0.006s
GCT: 总的gc耗时 0.008s

jinfo

usage : jinfo [opt] pid

实时查看和调整虚拟机启动参数
eg. jinfo -flag CMSInitiatingOccupancyFraction 41610
使用[+|-] name 修改一部分运行时虚拟机参数值
也可以使用 jps -v 来查看启动时默认参数
-XX:+PrintFlagsFinal 可以将参数打印出来

jmap

-dump 生成快照文件
eg. jmap -dump:format=b, file=path pid
-finalizerinfo 线上在F-Queue中等等Finalizer线程执行finalize方法的对象
-heap 线上Java堆详细信息
-histo 显示堆中对象的统计信息
-permstat 以classLoader为统计路径、显示永久代内存使用情况
-F 虚拟机不响应-dump时、使用-F强制生成dump文件

1
2
jmap -histo[:live] pid 显示堆中活跃对象
jmap -dump:[live,], file=filename 生成java堆

jhat

Usage: jhat -port 9000 dump-file

-port 指定端口
分析结果以为单位、分析内存泄露时、可能会用到 Heap Histogram(与 jmap -histo 功能一致)

jstack

stack trace for java生成虚拟机当前时刻的快照
Usage: jstack opt vmid

-F 正常的输出请求不被响应时、强制输出线程堆栈
-l 除堆栈外、显示线程的锁信息
-m 若调用本地方法、显示C/C++的线程堆栈

JVM参数解析

参数名称 含义 默认值 备注
-Xms 初始堆大小 物理内存的1/64(<1G) 默认(MinHeapFreeRatio参数可以调整)空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制.
-Xmx 最大堆大小 物理内存的1/4(<1G) 默认(MaxHeapFreeRatio参数可以调整)空余堆内存大于70%时,JVM会减少堆直到 -Xms的最小限制
-Xmn 年轻代大小 注意:此处的大小是(eden+ 2 survivor space)与jmap -heap中显示的New gen是不同的。 整个堆大小=年轻代大小 + 年老代大小 + 持久代大小.增大年轻代后,将会减小年老代大小.此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8
-Xss 每个线程的堆栈大小 JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K.更具应用的线程所需内存大小进行 调整.在相同物理内存下,减小这个值能生成更多的线程.但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右,一般小的应用, 如果栈不是很深, 应该是128k够用的 大的应用建议使用256k。这个选项对性能影响比较大,需要严格的测试。(较长)和threadstacksize选项解释很类似,官方文档似乎没有解释,在论坛中有这样一句话:””Xss is translated in a VM flag named ThreadStackSize”一般设置这个值就可以了。
-XX:NewRatio 年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代) -XX:NewRatio=4表示年轻代与年老代所占比值为1:4,年轻代占整个堆栈的1/5 Xms=Xmx并且设置了Xmn的情况下,该参数不需要进行设置。
-XX:SurvivorRatio Eden区与Survivor区的大小比值 设置为8,则两个Survivor区与一个Eden区的比值为2:8,一个Survivor区占整个年轻代的1/10
-XX:MaxTenuringThreshold 垃圾年龄的最大值 如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代. 对于年老代比较多的应用,可以提高效率.如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象再年轻代的存活 时间,增加在年轻代即被回收的概率 该参数只有在串行GC时才有效
-XX:PretenureSizeThreshold 对象超过多大是直接在老年代分配 0 单位字节 新生代采用Parallel Scavenge GC时无效,另一种直接在老年代分配的情况是大的数组对象,且数组中无外部引用对象.
-XX:LargePageSizeInBytes 内存页的大小不可设置过大, 会影响Perm的大小 =128m
-XX:+CollectGen0First FullGC时是否先YGC false
-XX:+UseFastAccessorMethods 原始类型的快速优化
-XX:+UseBiasedLocking 锁机制的性能改善
-XX:NewSize 年轻代大小(JDK 1.3/1.4)
-XX:MaxNewSize 年轻代最大值(JDK 1.3/1.4)
-XX:PermSize 设置持久代(perm gen)初始值 物理内存的1/64
-XX:MaxPermSize 设置持久代最大值 物理内存的1/4
-XX:ThreadStackSize Thread Stack Size (0 means use default stack size) [Sparc: 512; Solaris x86: 320 (was 256 prior in 5.0 and earlier); Sparc 64 bit: 1024; Linux amd64: 1024 (was 0 in 5.0 and earlier); all others 0.]
-XX:+AggressiveOpts 加快编译
并行收集器相关参数
参数名称 含义 默认值 备注
-XX:+UseParallelGC Full GC采用parallel MSC(此项待验证) 选择垃圾收集器为并行收集器.此配置仅对年轻代有效.即上述配置下,年轻代使用并发收集,而年老代仍旧使用串行收集.(此项待验证)
-XX:+UseParNewGC 设置年轻代为并行收集 可与CMS收集同时使用, JDK5.0以上,JVM会根据系统配置自行设置,所以无需再设置此值
-XX:ParallelGCThreads 并行收集器的线程数 此值最好配置与处理器数目相等 同样适用于CMS
-XX:+UseParallelOldGC 年老代垃圾收集方式为并行收集(Parallel Compacting) java6开始出现的参数
-XX:MaxGCPauseMillis 每次年轻代垃圾回收的最长时间(最大暂停时间) 如果无法满足此时间,JVM会自动调整年轻代大小,以满足此值.
-XX:+UseAdaptiveSizePolicy 自动选择年轻代区大小和相应的Survivor区比例 设置此选项后,并行收集器会自动选择年轻代区大小和相应的Survivor区比例,以达到目标系统规定的最低相应时间或者收集频率等,此值建议使用并行收集器时,一直打开.
-XX:GCTimeRatio 设置垃圾回收时间占程序运行时间的百分比 公式为1/(1+n)
-XX:+ScavengeBeforeFullGC Full GC前调用YGC true Do young generation GC prior to a full GC. (Introduced in 1.4.1.)
CMS相关参数
参数名称 含义 默认值 备注
-XX:+UseConcMarkSweepGC 使用CMS内存收集
-XX:CMSFullGCsBeforeCompaction 多少次后进行内存压缩 由于并发收集器不对内存空间进行压缩,整理,所以运行一段时间以后会产生”碎片”,使得运行效率降低.设置运行多少次GC以后对内存空间进行压缩,整理
-XX:+CMSParallelRemarkEnabled 降低标记停顿
-XX+UseCMSCompactAtFullCollection 在FULL GC的时候,对年老代进行压缩 CMS是不会移动内存的, 因此, 这个非常容易产生碎片, 导致内存不够用, 因此, 内存的压缩这个时候就会被启用
-XX:+UseCMSInitiatingOccupancyOnly 使用手动定义初始化定义开始CMS收集 禁止hostspot自行触发CMS GC
-XX:CMSInitiatingOccupancyFraction=70 使用cms作为垃圾回收使用70%后开始CMS收集 92 为了保证不出现promotion failed错误、设置需要满足:http://www.cnblogs.com/redcreen/archive/2011/05/04/2037057.html#CMSInitiatingOccupancyFraction_value
-XX:CMSInitiatingPermOccupancyFraction 设置Perm Gen使用到达多少比率时触发 92
-XX:+CMSIncrementalMode 设置为增量模式 适用于单CPU的情况
辅助信息
参数名称 含义 默认值 备注
-XX:+PrintGC [GC 118250K->113543K(130112K), 0.0094143 secs]
[Full GC 121376K->10414K(130112K), 0.0650971 secs]
-XX:+PrintGCDetails 输出形式:[GC [DefNew: 8614K->781K(9088K), 0.0123035 secs] 118250K->113543K(130112K), 0.0124633 secs] [GC [ParNew: 8614K->8614K(9088K), 0.0000665 secs][Tenured: 112761K->10414K(121024K), 0.0433488 secs] 121376K->10414K(130112K), 0.0436268 secs]
-XX:+PrintGCTimeStamps 输出每个阶段的gc时间
-XX:+PrintGCApplicationStoppedTime 打印垃圾回收期间程序暂停的时间.可与上面混合使用 输出形式:Total time for which application threads were stopped: 0.0468229 seconds
-XX:+PrintGCApplicationConcurrentTime 打印每次垃圾回收前,程序未中断的执行时间.可与上面混合使用 输出形式:Application time: 0.5291524 seconds
-XX:+PrintHeapAtGC 打印GC前后的详细堆栈信息
-Xloggc:filename 把相关日志信息记录到文件以便分析.与上面几个配合使用
-XX:+PrintTLAB 查看TLAB空间的使用情况
-XX:+PrintTenuringDistribution 查看每次minor GC后新的存活周期的阈值 Desired survivor size 1048576 bytes, new threshold 7 (max 15) new threshold 7即标识新的存周期的阈值为7

Java垃圾回收的依据是:是否还有引用.

什么是引用呢 ?

jdk1.2 之前的定义是:

若reference类型的数据中存储的数值代表一块内存的起始地址、则这块内存代表一个引用

jdk1.2 之后进行了扩充:

分为强引用软引用若引用虚引用.

如何定义 ?
强引用 (strong reference): 程序代码中普遍存在的、类似 Object obj = new Object() 这类的引用, 只要引用还在、永远不会被回收掉的对象

软引用 (soft reference):描述一些还有用、但不是必须的对象. 软引用关联的对象、在系统将要发生OOM前会对这些对象进行一次回收、若回收能够产生足够的空间、则不会发生OOM, 回收完成依然没有足够的空间才会抛出OOM异常, JDK1.2之后、系统提供了SoftReference来实现软引用

弱引用 (weak reference): 也是非必须对象、比软引用的引用更弱一些、被弱引用关联的对象只能生存到下次gc发生之前、当垃圾收集器工作时、无论当前内存是否足够、都会回收掉只被弱引用关联的对象
JDK1.2之后提供了WeakReference类来实现弱引用

虚引用 (Phantom reference): 一个对象是否有虚引用的存在、完全不影响其生存时间、也无法通过虚引用来取得一个对象的实例、设置虚引用的唯一目的就是能在整个对象进行垃圾收集时收到一个系统通知

看懂了gc日志、可能心中还有小小的疑惑?

为什么需要垃圾回收

在内存的动态分配和回收机制十分成熟的情况下、仍然没办法避免排查各种内存溢出、内存泄露的问题, 当垃圾收集称为系统达到更高并发量的瓶颈时、就需要了解gc的细节、对gc进行必要的监控和调节

程序计数器、虚拟机栈、本地方法栈 随线程运行结束而消亡、这几个区域的内存分配和回收具有确定性、不需要过多的考虑内存回收问题
而Java堆和方法区、则在运行时才知道要创建的对象、内存的分配是动态的、垃圾回收主要关注的是这部分的内存

如何判断对象已死?
  1. 引用计数法
    给对象添加一个引用计数器、当有新的引用时、计数器的值+1, 引用失效是、计数器的值-1, 计数器的值为0的对象就是不再有引用的对象
    这种方式的判断效率很高、实现也比较简单、但是不太好判断 循环引用的问题
    A->B, B->A
  1. 可达性分析
    通过 GC Roots 作为分析的起点、从这些节点向下搜索、若一个对象通过任意引用链不可达、则会被判断为可回收对象
1
2
3
4
5
可作为 `gc root` 的对象:
1. 虚拟机桟中引用的对象
2. 方法区中静态属性引用的对象
3. 方法区中常量引用的对象
4. 本地方法桟中JNI(Native方法)引用的对象
为什么gc的过程要stw ?

为了避免分析过程中对象的引用关系还在不断的发生变化、导致分析结果的准确性无法保证
系统停顿下来后如果得知对象引用关系呢 ?
在hotspot的实现中、有一个OopMap的数据结构、在类加载的时候, 它就把对象内什么偏移量位置上是什么类型的数据计算出来、在jit编译的过程中也会在特定的位置记录桟和寄存器哪些位置是引用、这样gc扫描时就可以直接得到了
但是、为什么是特定位置 ?
如果每条指令都生成对应OopMap、会需要大量的额外空间、所以只是在特定位置(安全点safepoint)记录这些信息
notice : 设置标记等待线程运行到安全点再gc解决了大部分问题、但如果线程是sleep或者block状态呢 ?线程无法响应jvm的中断请求、运行到安全点去中断挂起、jvm也不可能得到线程被重新分配CPU时间、so、有了安全区域-safe region来解决
safe region: 在一个代码片段之内、引用关系不会发生变化、在这个区域内的任意位置进行gc都是安全的,线程在进入安全区域的时候、会设置自己进入安全区域的标记、jvm在gc时、会忽略这类线程
在线程离开安全区域时会检测系统是否已经完成了gc、ok则可以继续运行、否则需要等待可以离开安全点的信号

晋升为老年代的判断?
  1. 对象优先在Eden区分配、若Eden区无足够的空间、虚拟机会发起一次Minor GC, 经过一次Minor gc、age+1、达到指定age(-XX:MaxTenuringThreshold指定)时、对象会进入老年代
  2. Minor gc时、无法放入 survivor 区的对象、会通过分配担保机制提前转移到old generation
  3. 大对象直接进入老年代, 为避免提前触发gc 大于 -XX:PreTenureThreshold指定值得对象会提前进入直接在老年代分配
  4. 若survivor区 相同年龄的所有对象的大小的总和>survivor区的一半、则 age >= 该age值得对象可以直接进入老年代、无需等到 -XX:MaxTenuringThreshold 指定年龄值

let’s start

知识的海洋是浩瀚的、有太多的好奇与未知。。。。
一直想要探索linux系统到底是如何运行而不得其法、偶然间遇到极课时间的一个linux系统优化的专栏、还不错、
写一下自己的收获吧、算是由表及里也好~

image.png
可以看到top的前半部分是系统统计信息、后半部分是进程信息
1行:任务队列信息,等同于uptime、从左到右依次为:
系统当前时间系统运行时间登录用户数
load avg 是系统平均负载、代表最近1min5min15min 的平均值
2行:进程统计信息总进程数正在运行进程数休眠进程数停止的进程数僵死进程数
3行:cpu统计信息 us:用户空间cpu占用率sy:内核空间cpu占用率ni用户进程空间改变过优先级的进程cpu占用率id空闲cpu占用率wa等待输入输出的cpu时间百分比hi硬中断请求si软中断请求
4行:内存统计信息 total:物理内存总量 free:空闲内存总量 used:已使用内存总量 内核缓冲使用量
5行:交换区使用情况

进程区字段含义:
pid: 进程id
user: 进程所有者的用户名
pr: 优先级
ni: nice值、负值表示高优先级
virt: 进程使用的虚拟内存总量
res: 进程使用的、未被换出的物理内存大小
shr: 共享内存大小
s: 进程状态
%cpu: 上次更新到现在的cpu时间占用百分比
%mem: 进程使用的物理内存百分比
time+: 进程使用的cpu时间总计,单位:1/100s
command: 命令名

  1. cpu使用率监控
    pidstat -t {pid} 1 3 -u 每隔1s输出1次、共输出3次系统状况
    pidstat -t {pid} 1 3 -u -t 同时输出线程使用情况

  2. io监控
    pidstat -t {pid} 1 3 -d -t 查看线程io信息

  3. 内存使用监控
    pidstat -t {pid} 1 3 -m -t 查看线程内存使用

image.png

各列含义如下:
procs:
r 等待运行的进程数
b 可中断休眠的进程数

memory: kb
swpd 虚拟内存的使用项目
free 空闲的内存
buff 被用来作为缓存的内存数

swap
si 从磁盘交换到内存的交换页数量、
so 从内存交换到磁盘的交换页数量、

io
bi 发送到块设备的块数
bo 从块设备接收到的块数

system
in 每秒的中断数包括时钟中断
cs 每秒的上下文切换数

cpu
us 用户cpu使用时间
sy 系统cpu使用时间
id 空闲时间