这些是我需要调整GC时通常会看到的一些准则和技巧。 主要由以下两本书组成,而根据我的经验却很少:

  • Java性能
  • JBoss AS 5性能调优

希望它们对那里的其他人有用!

垃圾收集器

XX:+AggressiveOpts将HotSpot内部布尔变量设置为true以启用其他性能优化

****************************************************** ******************************************************

由于大多数对象在其生命周期内最多只能被一个线程锁定,因此启用-XX:+ UseBiasedLocking可使该线程将锁定偏向自身。 一旦有偏见,该线程便可以随后锁定和解锁对象,而无需诉诸昂贵的原子指令

****************************************************** ******************************************************

要打印默认的人体工程学值:

java -XX:+PrintCommandLineFlags -version

****************************************************** ******************************************************

-XX:+PrintGCDetails打印更多且更有价值的垃圾收集信息。

以下示例显示了通过-XX:+UseParallelGC-XX:+UseParallelOldGC启用的Java 6 Update 25吞吐量垃圾收集器的-XX:+PrintGCDetails输出示例。 输出分布在多行中,以便于阅读。

[GC
[PSYoungGen: 99952K->14688K(109312K)]
422212K->341136K(764672K), 0.0631991 secs]
[Times: user=0.83 sys=0.00, real=0.06 secs]

****************************************************** ******************************************************

包括日期和时间戳

-XX:+PrintGCTimeStamps

YYYY-MM-DD-T-HH-MM-SS.mmm-TZ

-XX:+PrintGCDetails-Xloggc:<filename>结合使用时,即使不指定-XX:+PrintGCTimeStamps ,输出也会自动带有时间戳作为前缀。

****************************************************** ******************************************************

[Full GC (System)
[PSYoungGen: 99608K->0K(114688K)]
[PSOldGen: 317110K->191711K(655360K)]
416718K->191711K(770048K)
[PSPermGen: 15639K->15639K(22528K)],
0.0279619 secs]
[Times: user=0.02 sys=0.00, real=0.02 secs]

系统意味着代码中有一个System.gc()

****************************************************** ******************************************************

http://sysadminsjourney.com/2008/09/15/profile-gc-with-gchisto/
****************************************************** ******************************************************

VisualVM和VisualGC插件

如果远程,则需要安装jstatd守护程序

****************************************************** ****************************************************

分层服务器运行时是通过-server -XX:+TieredCompilationcommand行选项启用的。

小费

如果您不知道最初选择哪个运行时,请从服务器运行时开始。 如果无法满足启动时间或内存占用量要求,并且您正在使用Java 6 Update 25或更高版本,请尝试分层服务器运行时。 如果您没有运行Java 6 Update 25或更高版本,或者分层服务器运行时无法满足启动时间或内存占用量要求,请切换到客户端运行时。

****************************************************** ****************************************************

32位或64位JVM

操作系统 Java堆大小 32位或64位JVM
视窗 小于1300 MB 32位
视窗 介于1500 MB和32 GB之间[*] 64位-d64 -XX:+ UseCompressedOops命令行选项
视窗 超过32 GB 带-d64命令行选项的64位
的Linux 小于2 GB 32位
的Linux 2到32 GB之间[*] 64位-d64 -XX:+ UseCompressedOops命令行选项
的Linux 超过32 GB 带-d64命令行选项的64位
Oracle Solaris 小于3 GB 32位
Oracle Solaris 介于3到32 GB之间[*] 64位-d64 -XX:+ UseCompressedOops命令行选项
Oracle Solaris 超过32 GB 带-d64命令行选项的64位

[*]在具有-XX:+UseCompressedOops的64位HotSpot VM中,最佳性能约为最大Java堆大小大约26 GB或更小。

Java 6 Update 18以后的HotSpot VM版本默认基于最大Java堆大小自动启用-XX:+UseCompressedOops

****************************************************** ****************************************************

从parallelOldDC开始:古老的收藏集是多线程的

吞吐量垃圾收集器由HotSpot VM命令行选项-XX:+UseParallelOldGC-XX:+UseParallelGC 。 如果-XX:+UseParallelOldGC在您使用的HotSpot VM版本中不可用,请使用-XX:+UseParallelGC 。 两者之间的区别在于-XX:+UseParallelOldGC启用了多线程的年轻代垃圾收集器和多线程的旧代垃圾收集器,即次要垃圾收集和完整垃圾收集都是多线程的。 -XX:+UseParallelGC仅启用多线程年轻代垃圾收集器。 与-XX:+UseParallelGC一起使用的旧式垃圾收集器是单线程的。 使用-XX:+UseParallelOldGC也会自动启用-XX:+UseParallelGC 。 因此,如果要同时使用多线程年轻代垃圾收集器和多线程旧代垃圾收集器,则只需指定-XX:+UseParallelOldGC

****************************************************** ****************************************************

垃圾收集日志记录:

-XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xloggc:<filename>

在将HotSpot VM调整为低延迟时,以下两个命令行选项很有用,因为它们报告了由于VM安全点操作而导致应用程序被阻止的时间,以及应用程序在安全点操作之间执行了多长时间。

-XX:+PrintGCApplicationStoppedTime
-XX:+PrintGCApplicationConcurrentTime

选项-XX:+PrintSafepointStatistics可以帮助区分垃圾收集安全点和其他安全点。

-XX:+PrintGCApplicationConcurrentTime命令行选项可用于确定应用程序是否正在执行,以及在观察到的响应时间超过了应用程序要求的某个感兴趣的时间段内执行了多长时间。

****************************************************** ****************************************************

建议的GC日志记录命令行选项

GC命令行选项 最适用
-XX:+ PrintGCTimeStamps
-XX:+ PrintGC详细信息
-Xloggc:<文件名>
为所有应用程序启用的最少的命令行选项集。
-XX:PrintGCDateStamps 在希望查看日历日期和时间而不是指示自JVM启动以来的秒数的时间戳时使用。 需要Java 6 Update 4或更高版本。
-XX:+ PrintGCApplicationStoppedTime
-XX:+ PrintGCApplicationConcurrentTime
-XX:+ PrintSafepointStatistics
在调整应用程序以降低响应时间/延迟时很有用,有助于区分VM安全点操作和其他来源引起的暂停事件。

XX:+PrintCommandLineFlags在HotSpot VM初始化时将选定的初始堆大小和最大堆大小打印为-XX:InitialHeapSize=<n>

-XX:+PrintTenuringDistribution

****************************************************** ****************************************************** ************************

-XX:MaxHeapSize=<m> ,其中<n>是初始Java堆大小(以字节为单位), <m>是最大Java堆大小(以字节为单位)

****************************************************** ****************************************************** ************************

空间 命令行选项 占用率
Java堆 -Xms和-Xmx 完全垃圾收集后,老一代空间占用率为3到4倍
永久世代 -XX:PermSize -XX:MaxPermSize 完全垃圾收集后,永久生成空间占用率为1.2x到1.5x
年轻一代 -Xmn 完全垃圾收集后,老一代空间占用率为1到1.5倍
老一代 从Java总堆大小减去年轻代大小中隐含 完全垃圾收集后,老一代空间占用率为2到3倍

****************************************************** ****************************************************** ************************

年轻空间

-XX:NewSize=<n>[g|m|k]

-XX:MaxNewSize=<n>[g|m|k]

-Xmn<n>[g|m|k]

-Xmn可以方便地确定年轻一代空间的初始大小和最大大小

如果(-Xmx != -Xms) && -Xmn存在

Java堆大小的增长或收缩不会调整年轻代空间的大小。

随Java堆大小的任何增长或收缩,年轻代空间的大小将保持不变。 因此,仅当-Xms-Xmx设置为相同的值时, -Xmn应使用-Xmn

****************************************************** ****************************************************** ************************

烫发大小

-XX:PermSize=<n>[g|m|k]

-XX:MaxPermSize=<n>[g|m|k]

注重性能的Java应用程序应将初始和最大永久生成大小( -XX:PermSize-XX:MaxPermSize )的大小都设置为相同的值,因为增加或缩小永久生成空间需要完整的垃圾回收。

****************************************************** ****************************************************** ************************

-XX:-ScavengeBeforeFullGC将在完整垃圾收集上禁用年轻一代空间垃圾收集。

****************************************************** ****************************************************** ************************

2010-11-25T18:51:03.895-0600: [Full GC
[PSYoungGen: 279700K->267300K(358400K)][ParOldGen: 685165K->685165K(685170K)]
964865K->964865K(1043570K)
[PSPermGen: 32390K->32390K(65536K)],
0.2499342 secs]
[Times: user=0.08 sys=0.00, real=0.05 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space2010-11-25T18:26:37.755-0600: [Full GC
[PSYoungGen: 0K->0K(141632K)]
[ParOldGen: 132538K->132538K(350208K)]
32538K->32538K(491840K)[PSPermGen: 65536K->65536K(65536K)],
0.2430136 secs]
[Times: user=0.37 sys=0.00, real=0.24 secs]
java.lang.OutOfMemoryError: PermGen space

如果您在垃圾回收日志中观察到OutOfMemoryError ,请尝试将Java堆大小增加到JVM可用物理内存的80%到90%。

例如,对于旧世代空间OutOfMemoryErrors,增加-Xmsand -Xmx ;对于永久世代OutOfMemoryErrors,增加-XX:PermSize-XX:MaxPermSize

下一步是计算应用程序的实时数据大小。

****************************************************** ****************************************************** ************************

计算实时数据大小

除了实时数据大小外,处于稳态的完整垃圾收集还提供了由于完整垃圾收集而导致的最坏情况下的延迟。

您可以使用实时数据(应用程序繁忙时间内的perm空间+满GC后的旧空间)来计算初始堆大小:

通常,初始和最大Java堆大小命令行选项-Xms和-Xmx的值应设置为旧空间的实时数据大小的三到四倍。

完全垃圾回收后的旧一代空间占用为295111K,或大约295 MB。因此,实时数据大小为大约295 MB

因此,为此应用程序指定的建议初始Java堆大小和最大Java堆大小应为885到1180兆字节之间的值,即-Xms1180m -Xmx1180m是实时数据大小的四倍。

同样作为一般规则,初始和最大永久世代大小-XX:PermSize-XX:MaxPermSize应该比永久世代空间的活动数据大小大1.2倍至1.5倍。

在上图所示的示例完整垃圾收集中,完整垃圾收集后的永久生成空间占用为32390K,约32兆字节。 因此,为此应用程序指定的建议的初始和最大永久生成空间大小应在38兆字节和48兆字节之间,即-XX:PermSize = 48m -XX:MaxPermSize = 48m,是永久生成实时数据大小的1.5倍。

作为附加的一般规则,年轻代空间应为旧代空间活动数据大小的1到1.5倍。

结果,建议的年轻代大小应在295到442兆字节之间。 在上图中,年轻一代的空间大小为358400K,约358兆字节。 358兆字节在建议的大小以内。

如果初始和最大Java堆大小是实时数据大小的3倍至4倍,而年轻代空间是实时数据大小的1倍至1.5倍,则旧代空间的大小应在实时数据大小的2倍至3倍之间。

基于上图中的垃圾收集数据,应用这些常规大小调整规则的组合Java命令行为

$ java -Xms1180m -Xmx1180m -Xmn295m
-XX:PermSize=48m -XX:MaxPermSize=48m

空间 命令行选项 占用率
Java堆 -Xms和-Xmx 完全垃圾收集后,老一代空间占用率为3到4倍
永久世代 -XX:PermSize -XX:MaxPermSize 完全垃圾收集后,永久生成空间占用率为1.2x到1.5x
年轻一代 -Xmn 完全垃圾收集后,老一代空间占用率为1到1.5倍
老一代 从Java总堆大小减去年轻代大小中隐含 完全垃圾收集后,老一代空间占用率为2到3倍

****************************************************** ****************************************************** ************************

音调延迟/响应能力

评估垃圾收集器对延迟的影响涉及以下活动:

  • 测量次要垃圾收集时间
  • 测量次要垃圾收集频率
  • 测量最坏情况下的完整垃圾收集持续时间
  • 测量最坏情况下的全部垃圾收集频率

调整年轻代的大小

从parallelGC到并发的-XX:+UseConcMarkSweepGC

如果最坏的情况下,完整垃圾收集持续时间或频率收集频率太高

随着年轻一代人数的变化,要记住的其他一般准则是

  • 老一代的空间大小应不小于实时数据大小的1.5倍。 有关实时数据大小的定义和其他旧版本调整大小的准则,请参见上一节“ 确定内存占用空间 ”。
  • 年轻代的空间大小至少应为Java堆大小的10%,该值指定为-Xmx和-Xms。 很小的年轻一代可能适得其反。 它导致频繁的次要垃圾收集。
  • 增加Java堆大小时,请注意不要超过JVM可用的物理内存量。 Java堆大小消耗的内存足以导致基础系统交换到虚拟内存,从而导致垃圾收集器和应用程序性能下降。

调整旧一代的大小

这项任务的目的是评估由完整垃圾收集引起的最坏情况下的暂停时间以及完整垃圾收集的频率。

如果您仅观察完整的垃圾收集

在修改旧世代空间的大小时,旧世代大小可能会与年轻世代大小失去平衡,并导致应用程序仅经历完整的垃圾回收。 通常,这发生在旧的一代空间不够大而无法容纳所有从年轻一代空间提升的对象时,即使在进行完整的垃圾回收之后。

老式空间不够大的关键指标是,老式空间中的回收空间很小(ParOldGen标签右侧的值),并且在每个完整空间之后,大部分年轻空间仍然被占用。垃圾收集。 当旧一代中没有足够的空间来处理年轻一代的提升对象时,如先前输出中所观察到的,对象将“备份”到年轻一代空间中。

如果由于完整的垃圾收集持续时间太长而无法满足应用程序最坏情况下的延迟要求,那么您应该切换到使用并发垃圾收集器

使用HotSpot命令行选项启用并发垃圾收集器:

-XX:+UseConcMarkSweepGC

****************************************************** ****************************************************** ************************
避免幸存者空间溢出是通过调整幸存者空间的大小来实现的,以使幸存者空间足够大,可以将幸存的对象放置足够长的时间,以便在一段时间内老化。 有效的老化只会将寿命长的物体提升到旧的空间。

小费

老化是将对象保留在年轻一代中直至无法再访问的一种方法,以便为寿命更长的对象保留老一代空间。

使用HotSpot命令行选项确定幸存者空间的大小:
-XX:SurvivorRatio=<ratio>

<ratio>的值必须大于0。- -XX:SurvivorRatio=<ratio>表示每个幸存者空间与eden空间之间的空间比率。 以下公式可用于确定幸存者空间大小:
幸存者空间大小= -Xmn<value>/(-XX:SurvivorRatio=<ratio> + 2)

指定为比率的值越大,幸存者空间大小越小。
权属阈值解释

小费

在年轻一代中有效的对象老化可以防止它们过早地提升到老一代空间,从而降低了老一代的占用率。 这减少了CMS垃圾回收周期必须执行的频率,还减少了碎片的可能性。

还有一个HotSpot虚拟机命令行选项, -XX:MaxTenuringThreshold=<n>可用于询问HotSpot虚拟机仅一个对象的年龄之后,以促进对象的老一代空间超出的值<n>

对于Java 5 Update 6和更高版本,最大使用期限阈值可以设置为0–15,对于Java 5 Update 5和更低版本,可以设置为0–31。

不建议将最大使用期限阈值设置为0。这将导致在分配对象后,在下一个次要垃圾回收中将对象立即从年轻代升级到老一代。 这将非常Swift地扩展旧一代的空间,并导致频繁的完整垃圾收集。

还不建议将最大使用期限阈值设置为大于可能的最大值。 这将导致对象保留在幸存者空间中,直到幸存者空间溢出为止。 如果它们溢出,则对象将被无差别地提升为老一代,也就是说,它们不会根据其年龄来提升。 结果,可以在寿命较长的对象之前提升寿命较短的对象,这防止了有效的对象老化。

小费

通常,观察新的占位阈值始终小于最大占位阈值,或观察所需的幸存者大小小于幸存总字节数(对象年龄的最后一行和最右边的列的值)表明幸存者空间太小。

****************************************************** ****************************************************** ************************

启动CMS收集周期

停止世界压缩垃圾收集是最坏情况下垃圾收集导致的延迟

CMS周期的启动基于旧空间的占用

如果观察到世界各地的压缩垃圾收集,则可以调整CMS周期何时开始。 并发模式故障会在垃圾回收输出中标识CMS中的“停止世界”压缩垃圾回收。 以下是一个示例:

174.445: [GC 174.446: [ParNew: 66408K->66408K(66416K), 0.0000618
secs]174.446: [CMS (concurrent mode failure): 161928K->162118K(175104K),
4.0975124 secs] 228336K->162118K(241520K)

如果您在垃圾回收输出中观察到并发模式故障,则可以使用命令行选项指示HotSpot VM提前启动CMS周期的开始:

-XX:CMSInitiatingOccupancyFraction=<percent>

指定的值是CMS垃圾回收周期应开始的旧占用率的百分比。 例如,如果您希望CMS周期以旧的65%的空间占用率开始,则可以设置-XX:CMSInitiatingOccupancyFraction=65 。 第二个HotSpot命令行选项应与– XX:CMSInitiatingOccupancyFraction=<percent>结合使用

-XX:+UseCMSInitiatingOccupancyOnly

-Xmx1536m -Xms1536m -Xmn512m
-XX:CMSInitiatingOccupancyFraction = 51
-XX:+仅使用CMSInitiatingOccupancy

显式垃圾回收

如果观察到完整的垃圾回收,这些回收是通过显式调用System.gc() ,那么在使用并发垃圾回收器时有两种处理方法:

  1. 您可以使用HotSpot VM命令行选项请求HotSpot VM作为并发垃圾回收周期执行它们:
  2. -XX:+ ExplicitGCInvokesConcurrent
  3. 要么
  4. -XX:+ ExplicitGCInvokesConcurrentAndUnloadsClasses
  5. 首先需要Java 6或更高版本。 第二个要求Java 6 Update 4或更高版本。 如果您使用的JDK版本支持-XX:+ ExplicitGCInvokesConcurrentAndUnloadsClasses,通常会更好。
  6. 您可以使用Hotspot命令行选项让HotSpot VM忽略对System.gc()的显式调用:
  7. -XX:+ DisableExplicitGC
  8. 此命令行选项还忽略其他HotSpot VM垃圾回收器中对System.gc()的显式调用。

尽管在垃圾收集输出中报告了CMS Perm标签,但默认情况下,HotSpot VM不会通过CMS垃圾收集永久生成空间。 要启用CMS永久生成垃圾收集,您必须指定以下HotSpot VM命令行选项:
-XX:+CMSClassUnloadingEnabled
如果使用的是Java 6 Update 3或更早版本,则除了-XX:+ CMSClassUnloadingEnabled外,还必须指定以下命令行选项: -XX:+CMSPermGenSweepingEnabled

CMS暂停时间调整

备注阶段中使用的线程数可以由以下HotSpot VM命令行选项控制:

-XX:ParallelGCThreads=<n>

在某些情况下,可以通过指定以下内容来缩短备注阶段的持续时间:

-XX:+CMSScavengeBeforeRemark

此命令行选项强制HotSpot VM在CMS注释之前执行次要垃圾回收。 在备注之前进行次要垃圾回收,可以通过减少旧一代空间中可能到达的旧一代空间中的对象数量,来最大程度地减少备注阶段的工作量。

如果应用程序中有大量要处理的引用或可终结对象,则指定以下HotSpot VM命令行选项可以帮助减少垃圾回收时间:

-XX:+ParallelRefProcEnabled

最新和最优化

当新的性能优化集成到HotSpot VM中时,通常会在命令行选项-XX:+AggressiveOpts下引入它们。

如果应用程序涉众正在寻求其他性能并愿意接受与启用最新优化相关的其他小风险,则应考虑使用-XX:+AggressiveOpts命令行选项。

转义分析

转义分析是一种评估Java对象范围的技术。 特别是,如果某个执行线程分配的Java对象可以被其他线程看到,则该对象“转义”。 如果Java对象无法转义,则可以应用其他优化技术。 因此,优化技术称为逃逸分析。

使用以下命令行选项启用HotSpot VM中的转义分析优化:

-XX:+DoEscapeAnalysis

Linux上的大页面

-XX:+UseLargePages

参考:“ 垃圾收集器”指南和 JCG合作伙伴 Marco Castigliego的技巧 ,位于“ 删除重复并修复不良名称”博客上。

翻译自: https://www.javacodegeeks.com/2013/12/garbage-collector-guidelines-and-tips.html

垃圾收集器准则和提示相关推荐

  1. 垃圾收集算法,垃圾收集器_垃圾收集器准则和提示

    垃圾收集算法,垃圾收集器 这些是我需要调整GC时通常会看到的一些准则和技巧. 主要由以下两本书组成,而根据我的经验却很少: Java性能 JBoss AS 5性能调优 希望它们对在那里的其他人有用! ...

  2. java8默认内存收集器_使用正确的垃圾收集器将Java内存使用量降至最低

    java8默认内存收集器 大小对于软件至关重要. 很明显,与大的整体方法相比,在微服务体系结构中使用小片段具有更多优势. 最新的Java版本的Jigsaw有助于分解旧应用程序或从头开始构建新的云原生应 ...

  3. java g1 收集调优_Java性能调优:充分利用垃圾收集器

    java g1 收集调优 JVM背后发生了什么,垃圾回收如何影响Java性能? 性能调优世界是一个危险的地方,一个JVM标志失衡,事情很快就会变得繁琐. 因此 ,我们决定求助于Java性能调优专家, ...

  4. 使用正确的垃圾收集器将Java内存使用量降至最低

    大小对于软件至关重要. 很明显,与大型整体方法相比,在微服务体系结构中使用小型组件具有更多优势. 最新的Java版本的Jigsaw可帮助分解旧应用程序或从头开始构建新的云原生应用程序. 这种方法减少了 ...

  5. Java性能调优:充分利用垃圾收集器

    JVM背后发生了什么,垃圾回收如何影响Java性能? 性能调优世界是一个危险的地方,一个JVM标志失衡,事情很快就会变得繁琐. 因此 ,我们决定求助于Java性能调优专家, 单调 JVM探查器mjpr ...

  6. 垃圾收集器与内存分配策略系列(三)

    经典垃圾收集器 1. Serial收集器 2. ParNew收集器 3. Parallel Scavenge收集器 4. Serial Old收集器 5. Parallel Old收集器 6. CMS ...

  7. JVM面试题整理-Java内存区域与内存溢出异常、垃圾收集器和内存分配策略

    参考: https://blog.csdn.net/zd836614437/article/details/64126826 https://blog.csdn.net/u011225629/arti ...

  8. JVM垃圾收集—垃圾收集器及常见组合参数

    链接: JVM垃圾收集-垃圾收集算法 上一篇介绍了垃圾收集算法及分区,这篇我们来学习垃圾收集器 文章目录 Serial ParNew Parallel Scavenge Serial Old Para ...

  9. 深入理解Java虚拟机(第三版)--经典垃圾收集器

    Serial收集器 Serial收集器是最基础.历史最悠久的收集器,曾经(在JDK 1.3.1之前)是HotSpot虚拟机新生代收集器的唯一选择.大家只看名字就能够猜到,这个收集器是一个单线程工作的收 ...

最新文章

  1. Cordova error:npm install -g ios-deploy
  2. 拉格朗日乘数法学习笔记
  3. Linux软件管理器(如何使用软件管理器来管理软件)
  4. 从MongoDB GridFS流式传输文件
  5. 11 CO配置-控制-成本中心会计-定义分割结构
  6. 【JS】变量、作用域和内存问题
  7. 机器学习:单变量线性回归及梯度下降
  8. 三菱fx编程手册_三菱FX串口PLC远程编程调试流程
  9. java社区团购微信小程序源码
  10. Value-Decomposition Networks For Cooperative Multi-Agent Learning(VDN)
  11. tex常用函数 上下行对齐_latex 部分右对齐
  12. Linux如何进BIOS看硬盘,bios模式下怎么看硬盘
  13. python汇率转换代码中美_如何实现python汇率转换代码
  14. 2020年国赛密码学湖湘杯密码学第一题writeup
  15. navicat 表合并查询_navicat怎么合并表格
  16. 邮件群发平台_招聘平台挑选邮件群发平台时应该注意什么
  17. Windows环境下启动zookeeper错误:Zookeeper audit is disabled
  18. Linux介绍以及常用操作命令
  19. 基于深度学习的大规模交通标志识别(附6GB交通标志数据集)
  20. java zip 读取_java读取zip (含压缩包内的文件)

热门文章

  1. 自增主键与UUID的优缺点
  2. data layui table 排序_浅谈layui中table的sort排序
  3. 互换性与技术测量教材pdf_【检验】临床生物化学检验技术(第6版)人民卫生出版社【电子教材PDF】【人卫教材电子版】...
  4. 知识复习(LDT+TSS+GATE+INTERRUPT)
  5. Java 流式编程stream
  6. i18n国际化登录页面
  7. cloudwatch_将CloudWatch Logs与Cloudhub Mule集成
  8. lucene学习笔记_学习Lucene
  9. java中使用kotlin_在Kotlin中使用libGDX
  10. JUnit 5中的测试执行顺序