欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

tomcat内存溢出解决

程序员文章站 2022-04-16 08:52:43
...

建议您创建一个名为setenv的文件。 蝙蝠和地点在Tomcat bin目录。 与这个文件(这是由卡特琳娜。 蝙蝠和卡特琳娜。 sh脚本),您可以更改以下Tomcat环境设置JAVA_OPTS变量:

你可以设置最小和最大内存堆大小

JVM xms和- xmx参数 

最好的限制取决于许多条件,如转换,积分器ETL应该执行。 发现的信息转换,建议最多1 GB。 例如,将最小堆大小设置为128 MB,最大堆大小为1024 MB,使用

JAVA_OPTS=-Xms128m -Xmx1024m

你应该设定的最大极限PermGen(永久代)内存空间大小大于默认。 默认的64 MB是不够的企业应用程序。 一个合适的内存限制取决于不同的标准,但256 MB在大多数情况下将使一个不错的选择。 如果PermGen空间最大太低,OutOfMemoryError:PermGen空间可能会犯错误。 你可以设置JVM PermGen最大限度地使用以下参数

-XX:MaxPermSize=256m

由于性能原因,建议应用程序是运行在服务器模式。 Apache Tomcat不运行在默认服务器模式。 你可以设置使用JVM - Server服务器模式参数。 你可以设置JVM参数JAVA_OPTS变量在setenv环境变量文件。

The following is an example of a setenv.bat file:

set "JAVA_OPTS=%JAVA_OPTS% -Xms128m -Xmx1024m -XX:MaxPermSize=256m -server"

为懒惰的读者完整清单在这里提供了好奇的详细说明(下图):

  • Java < 8
-server
    -Xms<heap size>[g|m|k] -Xmx<heap size>[g|m|k]
    -XX:PermSize=<perm gen size>[g|m|k] -XX:MaxPermSize=<perm gen size>[g|m|k]
    -Xmn<young size>[g|m|k]
    -XX:SurvivorRatio=<ratio>
    -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled
    -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=<percent>
    -XX:+ScavengeBeforeFullGC -XX:+CMSScavengeBeforeRemark
    -XX:+PrintGCDateStamps -verbose:gc -XX:+PrintGCDetails -Xloggc:"<path to log>"
    -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M
    -Dsun.net.inetaddr.ttl=<TTL in seconds>
    -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=<path to dump>`date`.hprof
    -Djava.rmi.server.hostname=<external IP>
    -Dcom.sun.management.jmxremote.port=<port> 
    -Dcom.sun.management.jmxremote.authenticate=false 
    -Dcom.sun.management.jmxremote.ssl=false
  • Java > = 8
-server
    -Xms<heap size>[g|m|k] -Xmx<heap size>[g|m|k]
    -XX:MaxMetaspaceSize=<metaspace size>[g|m|k]
    -Xmn<young size>[g|m|k]
    -XX:SurvivorRatio=<ratio>
    -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled
    -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=<percent>
    -XX:+ScavengeBeforeFullGC -XX:+CMSScavengeBeforeRemark
    -XX:+PrintGCDateStamps -verbose:gc -XX:+PrintGCDetails -Xloggc:"<path to log>"
    -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M
    -Dsun.net.inetaddr.ttl=<TTL in seconds>
    -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=<path to dump>`date`.hprof
    -Djava.rmi.server.hostname=<external IP>
    -Dcom.sun.management.jmxremote.port=<port> 
    -Dcom.sun.management.jmxremote.authenticate=false 
    -Dcom.sun.management.jmxremote.ssl=false

使服务器的服务器

-server

Java VM服务器应用程序特有的特性,如sofisticated JIT编译器。 虽然这个选项是暗中支持x64虚拟机,它仍然使意义上使用它根据文档行为也许在未来改变。

让你堆显式

-Xms<heap size>[g|m|k] -Xmx<heap size>[g|m|k]

为了避免动态堆调整和滞后,这可能是由于这一点,我们影响指定最小和最大的堆大小。 因此Java VM将花时间在所有堆只有一次提交。

-XX:PermSize=<perm gen size>[g|m|k] -XX:MaxPermSize=<perm gen size>[g|m|k]

永久代是一样的逻辑整体堆——预定义上浆避免成本的动态变化。 不适用于Java > = 8。

-XX:MaxMetaspaceSize=<metaspace size>[g|m|k]

默认Metaspace Java VM 8不是有限的,但为了系统的稳定性是有意义的限制一些有限的价值。

-Xmn<young size>[g|m|k]

影响年轻一代的定义大小。

-XX:SurvivorRatio=<ratio>

比决定survivour空间相对伊甸园的大小尺寸。 比率可以计算使用以下公式:

幸存者比率  年轻的大小  幸存者大小  − 

了解更多 和 这个太 

使GC对吧

-XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled

作为服务器应用程序的响应时间是至关重要的并发收集器英尺适合Web应用程序。 annihilate G1还不生产准备好了,因此我们不得不使用并发标记-清除收集器。

-XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=<percent>

默认情况下CMS GC使用启发式规则触发垃圾回收。 这使GC难以预测,通常倾向于收集延迟到年老代几乎占领了。 启动它事先允许旧一代充满前完成收集,从而避免完整GC(即停止一切暂停)。 - xx:+ UseCMSInitiatingOccupancyOnly 防止使用GC启发式。- xx:CMSInitiatingOccupancyFraction 告诉Java VM当CMS应该触发。 基本上,它允许在堆中创建一个缓冲区,可以填满数据,而CMS是有效的。 因此应该重新计算百分比从内存消耗的速度在老一辈生产负荷。 这些百分比应该仔细选择,如果这将是小- CMS将经常工作,如果这将是大- CMS会太晚,触发 并发模式失败 可能发生。 通常- xx:CMSInitiatingOccupancyFraction 应该在70级,这意味着应用程序应该使用更少,70%的老的一代。

-XX:+ScavengeBeforeFullGC -XX:+CMSScavengeBeforeRemark

指导年轻一代垃圾收集器收集之前做完整GC或CMS备注阶段和结果improvde由于没有需要检查他们的表现年轻一代之间的引用和终身。

了解更多 和 一些新鲜的 

GC日志记录

-XX:+PrintGCDateStamps -verbose:gc -XX:+PrintGCDetails -Xloggc:"<path to log>"

这些选项让Java垃圾收集器记录活动到指定的文件中。 所有记录将前缀与人类可读的日期和时间。 与此同时,你应该避免使用 - xx:+ PrintGCTimeStamps 因为它会预谋和无用的时间戳记录以来Java应用程序开始。

生成日志可以稍后分析 GCViewer 

-XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M

GC日志文件旋转使垃圾收集问题的分析更容易,也保证磁盘免受过度消费空间。

了解更多 和 多一点 

DNS缓存

-Dsun.net.inetaddr.ttl=<TTL in seconds>

的秒数在此期间将在Java VM缓存DNS记录。 违约行为的Java VM 6永远是缓存,不脚服务器应用程序的需求,当你不想每次重新启动服务器,当IP改变了DNS记录。 它已经改变了在Java VM 7缓存30秒钟,但前提是安全管理器没有安装。 根据版本的Java VM和存在的安全管理器缓存DNS记录还可以无限。 
通常推荐的选项是禁用DNS缓存,可以性能下降的原因。 请求DNS synchorized块执行,仅执行一个请求在任何时间点。 因此,如果您的应用程序是havily利用网络将经历饱和DNS请求,所以TTL值 应该 从来没有 被使用。

更好的解决方案是为合理的缓存不长时间,例如1分钟( 60 秒)。 这意味着您的应用程序交互系统必须保证两个不同的ip将继续正常工作在这1分钟,否则降低TTL值应该选择。 这应该是合理的(不等于 ),以防止可能的争用请求DNS。

这个选项是方便使用,但是 networkaddress.cache.ttl 中指定% % JRE / lib / security / java。 安全应该被认为是更好的解决方案,至少从官方文档潜在。

了解更多 

内存转储

-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=<path to dump>`date`.hprof

如果您的应用程序会失败在生产内存不足,你不想等待另一个机会来重现该问题。 这些选项指示Java VM内存转储到文件,当伯父发生。 它可能导致相当大的停顿大伯父活动期间堆。 然而,如果Java VM是伯父,收集尽可能多的信息关于这个问题比努力更重要交通完全破碎的应用程序服务。 我们也确保转储将使用名称创建独特的每个应用程序启动时间(这是requeired因为Java VM将无法覆盖现有的文件)。

了解更多 

让JMX的工作

-Djava.rmi.server.hostname=<external IP>

IP地址,这将是嵌入到RMI存根发给客户。 后来客户将使用这个存根通过RMI与服务器通信。 在现代数据中心机通常有两个IPs(内部和外部)你想要显式地指定使用哪个IP,否则JVM将使它自己的选择。 正确的该属性值使用JMX是成功的先决条件。

-Dcom.sun.management.jmxremote.port=<port> 
-Dcom.sun.management.jmxremote.authenticate=false 
-Dcom.sun.management.jmxremote.ssl=false

-Dcom.sun.management.jmxremote 选项不需要从Java VM 6开始,然而让JMX可用于远程访问特定听应提供港口。 后来这个端口可以使用任何JMX工具(如用于连接。 VisualVM 或 Java任务控制 )。

还减少额外的麻烦与连接禁用标准认证,但确保只有经过授权的用户可以使用防火墙连接到环境。 如果出于安全考虑,你还是想控制通过标准的访问机制 了解更多 

注:

许多选项以前非常有用的更新在Java VM(特别是发布Java 7)默认预配置:

  • - xx:+ UseCompressedOops
  • -Dsun.rmi.dgc.server。 gcInterval = 3600000和-Dsun.rmi.dgc.client.gcInterval = 3600000
  • -Dcom.sun.management.jmxremote


转载于:https://my.oschina.net/liting/blog/536475