• 11月23日 星期六

高效应用程序的7个JVM参数

围绕垃圾回收和内存,您可以将600多个参数传递给JVM。如果包括其他方面,JVM参数的数量将很容易超过1000+。任何人都无法消化和理解太多的论据。在本文中,我们将重点介绍您可能会有用的七个重要JVM参数。

高效应用程序的7个JVM参数


1. -Xmx和-XX:MaxMetaspaceSize

-Xmx可能是最重要的JVM参数。-Xmx定义要分配给应用程序的最大堆大小。(要了解JVM中的不同内存区域,您可以观看此短片)。您可以这样定义应用程序的堆大小:

java

1个

- Xmx2g


堆大小在确定您的以下方面起着至关重要的作用:


一个。应用程序性能。

b。Bill,您将从云提供商(AWS,Azure等)获得收益

这就提出了一个问题,我的应用程序正确的堆大小是多少?我应该为应用程序分配大堆大小还是小堆大小?答案是:“取决于情况。” 在本文中,我们分享了关于需要使用大堆还是小堆的想法。

元空间是将存储JVM的元数据定义(例如类定义,方法定义)的区域。默认情况下,可用于存储此元数据信息的内存量是无限的(即受您的容器或计算机的RAM大小的限制)。您需要使用:XX:MaxMetaspaceSize参数指定可用于存储元数据信息的内存量的上限。

java

1个

- XX:MaxMetaspaceSize = 256个米

2. GC算法

截至2020年3月,OpenJDK中有7种不同的GC算法:

1. 串行GC。

2. 平行GC

3. 并发标记和扫描GC。

4. G1 GC。

5. 雪兰多厄GC。

6. Z GC。

7. Epsilon GC。

如果您未明确指定GC算法,那么JVM将选择默认算法。在Java 8之前,并行GC是默认的GC算法。从Java 9开始,G1 GC是默认的GC算法。

GC算法的选择对于确定应用程序的性能起着至关重要的作用。根据我们的研究,我们使用Z GC算法观察到了出色的性能结果。如果使用JVM 11+,则可以考虑使用Z GC算法(即-XX:+ UseZGC)。有关Z GC算法的更多详细信息,请参见此处。

下表总结了激活每种垃圾收集算法所需传递的JVM参数。

GC算法

JVM参数

串行GC

-XX:+ UseSerialGC

平行气相色谱

-XX:+ UseParallelGC

并发市场和扫描(CMS)GC

-XX:+ UseConcMarkSweepGC

G1 GC

-XX:+ UseG1GC

雪兰多GC

-XX:+使用ShenandoahGC

Z气相色谱

-XX:+ UseZGC

Epsilon GC

-XX:+ UseEpsilonGC

3.启用GC日志记录

垃圾收集日志包含有关垃圾收集事件,回收的内存,暂停时间长度等信息。您可以通过传递以下JVM参数来启用垃圾收集日志:

从JDK 1到JDK 8:


1个

-XX:+ PrintGCDetails -XX:+ PrintGCDateStamps -Xloggc:{文件路径}


从JDK 9及更高版本开始:


java

1个

- 的Xlog:GC *:文件= { 文件- 路径 }


例:


java

1个

- XX:+ PrintGCDetails - XX:+ PrintGCDateStamps - Xloggc:/ 选择/ 工作区/ myAppgc。日志

2

- 的Xlog:GC *:文件= / 选择/ 工作区/ myAppgc。日志


通常,GC日志用于调整垃圾回收性能。但是,GC日志包含重要的微观指标。这些指标可用于预测应用程序的可用性和性能特征。


在本文中,我们将重点介绍一种这样的测微:“ GC吞吐量 ”(要了解其他可用的测微的更多信息,您可以参考本文)。GC吞吐量是您的应用程序在处理客户交易中花费的时间与它在处理GC活动中花费的时间之比。如果您的应用程序的GC吞吐量为98%,则意味着您的应用程序将其98%的时间用于处理客户活动,而其余2%用于GC活动。

4. -XX:+ HeapDumpOnOutOfMemoryError,-XX:HeapDumpPath

OutOfMemoryError是一个严重的问题,它将影响应用程序的可用性/性能SLA。为了诊断OutOfMemoryError或任何与内存相关的问题,必须在应用程序开始体验之前或此时捕获堆转储OutOfMemoryError。

由于我们不知道何时OutOfMemoryError会抛出,很难在适当的时候手动捕获堆转储。但是,可以通过传递以下JVM参数来自动化捕获堆转储:

-XX:+HeapDumpOnOutOfMemoryError and -XX:HeapDumpPath={HEAP-DUMP-FILE-PATH}

在中-XX:HeapDumpPath,您需要指定存储堆转储的文件路径。当您传递这两个JVM参数时,堆转储将在OutOfMemoryError抛出时自动捕获并写入定义的文件路径。例:

java

1个

- XX:+ HeapDumpOnOutOfMemoryError - XX:HeapDumpPath = / 崩溃/ 我的- 堆- 转储。hprof

一旦捕获了堆转储,就可以使用HeapHero或 EclipseMAT之类的工具来分析堆转储。

OutOfMemoryError可以在本文中找到有关JVM参数的更多详细信息。

5. -Xss

每个应用程序将具有数十,数百,数千个线程。每个线程都有自己的堆栈。在每个线程的堆栈中,存储以下信息:

· 当前执行的方法/功能。

· 原始数据类型。

· 变量。

· 对象指针。

· 返回值。

他们每个人都消耗内存。如果他们的消费超出某个限制,则StackOverflowError抛出a。有关此问题的更多详细信息StackOverflowError和解决方案,请参见本文。但是,可以通过传递-Xss参数来增加线程的堆栈大小限制。例:


1个

-Xss256k

如果将此-Xss值设置为一个很大的数字,则将阻塞并浪费内存。假设您将-Xss值分配为2mb,而只需要256kb,那么您将浪费大量的内存,而不仅仅是1792kb(即2mb – 256kb)。你想知道为什么吗?

假设您的应用程序有500个线程,然后-Xss值为2mb,则您的线程将消耗1000mb的内存(即500个线程x 2mb /线程)。另一方面,如果仅分配-Xss给256kb,则线程将仅消耗125mb的内存(即500个线程x 256kb /线程)。每个JVM将节省875mb(即1000mb – 125mb)内存。是的,它将产生巨大的变化。

注意:线程是在堆(即-Xmx)之外创建的,因此这1000mb将是-Xmx您已经分配的值的补充。要了解为什么在堆外部创建线程,您可以观看此简短视频片段。

我们的建议是从一个低值(例如256kb)开始。使用此设置运行彻底的回归,性能和AB测试。仅当您遇到a时StackOverflowError,才可以增加价值;否则请考虑保持较低的价值。

6. -Dsun.net.client.defaultConnectTimeout和-Dsun.net.client.defaultReadTimeout

现代应用程序使用多种协议(即SOAP,REST,HTTP,HTTPS,JDBC,RMI等)与远程应用程序连接。有时远程应用程序可能需要很长时间才能做出响应。有时他们可能根本不响应。

如果没有正确的超时设置,并且远程应用程序的响应速度不够快,则您的应用程序线程/资源将被卡住。远程应用程序无响应可能会影响您的应用程序的可用性。它可以使您的应用程序停止运行。为了保护应用程序的高可用性,应配置适当的超时设置。

您可以在JVM级别传递这两个强大的超时网络属性,这些属性可以全局适用于所有使用java.net.URLConnection的协议处理程序:

1. sun.net.client.defaultConnectTimeout指定建立到主机的连接的超时(以毫秒为单位)。例如,对于HTTP连接,它是与HTTP服务器建立连接时的超时。

2. 当建立与资源的连接时,sun.net.client.defaultReadTimeout指定从输入流读取时的超时(以毫秒为单位)。

例如,如果您要将这些属性设置为2秒:


1个

-Dsun .net.client .defaultConnectTimeout = 2000 -Dsun .net.client .defaultReadTimeout = 2000

注意:默认情况下,这两个属性的值为-1,这表示未设置超时。有关这些属性的更多详细信息,请参见本文。

7. -Duser.timeZone

您的应用程序可能在某个时间/日期附近具有敏感的业务需求。例如,如果您正在构建交易应用程序,则无法在上午9:30之前进行交易。为了实现那些与时间/日期相关的业务需求,您可能正在使用java.util.Date或java.util.Calendar对象。

默认情况下,这些对象从底层操作系统中获取时区信息。如果您的应用程序在分布式环境中运行,这将成为一个问题。看一下以下情况:

· 如果您的应用程序跨多个数据中心(例如,旧金山,芝加哥,新加坡)运行,则每个数据中心中的JVM最终将具有不同的时区。因此,每个数据中心中的JVM将表现出不同的行为。这将导致结果不一致。

· 如果要在云环境中部署应用程序,则可能会在您不知情的情况下将应用程序移动到其他数据中心。同样在这种情况下,您的应用程序最终将产生不同的结果。

· 您自己的运营团队还可以更改时区,而无需掌握开发团队的知识。它还会歪曲结果。

为了避免这些麻烦,强烈建议使用Duser.timezonesystem属性在JVM上设置时区 。例如,如果要为应用程序设置EDT时区,则可以执行以下操作:

java

1个

- Duser。时区= 美国/ 东部

结论

在本文中,我们试图总结一些重要的JVM参数及其积极影响。希望对您有所帮助。

最后,开发这么多年我也总结了一套学习Java的资料与面试题,如果你在技术上面想提升自己的话,可以关注我,私信发送领取资料或者在评论区留下自己的联系方式,有时间记得帮我点下转发让跟多的人看到哦。

高效应用程序的7个JVM参数


高效应用程序的7个JVM参数

上一篇新闻

「InfoSec」云生态的安全挑战

下一篇新闻

新加坡150万病人资料被黑客窃取,包括李显龙开药记录

评论

订阅每日新闻

订阅每日新闻以免错过最新最热门的新加坡新闻。