java内存不足错误_关于性能:Java中的正常降级以避免内存不足错误

针对Java服务在处理大量内存请求时可能出现的问题,讨论了如何通过使用资源池、固定线程池和有界队列限制并发执行,以及在内存不足时的优雅降级方法。文章提出了监控内存使用并根据统计信息调节服务,以及使用信号量控制工作量的思路,以避免内存不足错误和长时间GC暂停。此外,还提到了应用服务器的负载平衡和工作线程池配置作为解决方案的一部分。
摘要由CSDN通过智能技术生成

在突发大量内存的请求期间,哪些工具或最佳实践可用于在Java服务中正常降级服务? 有问题的应用程序是多线程的。 处理每个请求所需的工作量可能相差很大,并且不容易拆分和并行化。

我很担心编写与堆使用和GC有关的应用程序级代码,但是我们发现,通过处理多个密集的请求,应用程序可能会陷入麻烦,这意味着内存不足错误或完整的GC。 完整的GC通常无法找到任何可用内存。

长话短说:我正在考虑增加一些限制或排队功能来避免这种问题。

任何想法或建议表示赞赏。

我假设您已对应用程序进行了概要分析,以确保您无法减少所使用的内存量。 另外,您还检查过无法获得更大的服务器,一台16 GB的PC可能要花费您$ 1000。

彼得-是的,我们已经对应用程序进行了分析,以了解可以减少内存使用量的地方。 更多的物理内存,更大的服务器-这些选项在发生时是否可能不会导致GC变得更长,更痛苦?

GC的成本与所使用的数量成正比,而与免费数量成反比。 如果您使用相同的内存量,则GC暂停将是相同的,但频率要少得多。 如果您使用更多的内存,它将更长,但这比完全失败更好。

这是Netty作者的一个实现示例(链接)。他们基本上会跟踪内存使用情况,并根据该统计信息直接进行调节。

另一个更粗略的方法是使用固定线程池和有界队列来限制并发执行。一种常见的方法是,一旦此队列已满,就让queue.put()的调用者自己执行任务。这样,负载(应该是)将一直传播回客户端,直到新请求的创建变慢为止。因此,应用程序的行为。变得更加"优雅"。

实际上,我几乎只使用上述"粗略"方式。效果很好。基本上,固定线程池和有界队列的组合+调用方运行拒绝策略。我使参数(队列大小,线程池大小)保持可配置状态,然后在完成设计之后,我将调整这些参数。有时,很明显可以在服务等之间共享线程池,因此在这种情况下,使用类ThreadPoolExecutor来获取固定在一个线程池中的固定线程池/有界队列/调用方运行策略确实非常方便。

如joeslice所说,通过一个简单的资源池实现限制。从最基本的角度来看,这是一个信号灯-您的工作线程在处理请求之前需要获得许可。由于您说自己有各种各样的任务,因此您可能希望许可证稍微复杂一些,例如获得与工作规模成比例的一定数量的许可证。

过去,我发现这并不总是有效。假设您的启发式功能已关闭,并且您的应用仍然抛出了OOM。重要的是要防止进程在不良状态下徘徊,因此请立即终止并重新启动该进程。有几种方法可以通知OOM何时发生,例如看到Java内存不足,然后退出。

该过程不必挂在坏状态。 OOM将展开有问题的线程的堆栈,从而释放一些内存。 在线程池中,可以捕获OOM并稍微调整试探法,以考虑更改后的请求模式。 整个应用程序可以生存并继续提供服务。

OOM可能有多种原因,其中只有一种是由信号量/启发式方法控制的,因此我认为您所说的不可靠。 换句话说,捕获OOM有时可能会起作用,但Ive发现安全起来比后悔要好得多。 保留GC和应用程序日志,以便稍后在生产环境之外重现问题!

您正在使用J2EE吗?因为这是Application Server进行负载平衡的工作,并且我敢肯定许多主流AppServer都支持它。您的应用程序不必关心它。

在应用程序服务器中,通常有工作线程池的设置。该池中的最大线程数大致定义了您将消耗多少内存。这是一个简单且重要的工作概念。

我不会称其为"优雅降级"。这是节流的。正常降级涉及降低服务级别(例如,提供给用户的详细信息的数量),以至少使每个当前用户都可以使用基本必需的功能。随着节流,额外的用户就走运了。

根据该定义进行的正常降级需要了解应用程序的性质,因此您必须使代码对此有所了解。

一种明显的方法是根据用户的需要将所有可能的操作分为几类。一等舱应始终处理。仅当服务器低于特定负载级别时,才服务第二(第三,第四,...)类,否则将返回"暂时不可用"错误。

我想知道是否有一种方法可以预先确定给定工作将使用多少内存...。如果有某种方法可以确定特定的输入可能会产生爆炸性的内存大小,也许您可??以尝试保持它不会与另一个高使用率作业同时运行。

如果您可以确定每个工作之间的相对大小(这是一个很大的假设),则可以使用计数信号量(例如)允许一次运行100个单位的工作。一个典型的工作可能只算作一个单元(并且只获取一个许可),而较大的工作在运行前可能需要获取10或20个许可。

当然,如果您无法预先确定要使用的内存大小,则仍然可以探索进一步细分问题的方法,以便您执行大量的小型内存工作,而不是少数大工作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值