Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
调整JavaGC,使其立即抛出OOME,而不是不确定地减速_Java_Performance_Memory Management_Garbage Collection_Jvm - Fatal编程技术网

调整JavaGC,使其立即抛出OOME,而不是不确定地减速

调整JavaGC,使其立即抛出OOME,而不是不确定地减速,java,performance,memory-management,garbage-collection,jvm,Java,Performance,Memory Management,Garbage Collection,Jvm,我注意到,有时,当内存几乎耗尽时,GC试图以任何性能代价完成(导致程序几乎冻结,有时几分钟),而不是立即抛出OOME(OutOfMemoryError) 有没有办法在这方面调整GC 将程序速度降至接近零会使其无响应。在某些情况下,最好有一个响应“我死了”而不是根本没有响应。我不知道有什么方法可以按照您描述的方式配置Java垃圾收集器 一种方法可能是让应用程序主动监控可用内存量,例如使用,并在低于某个阈值且无法通过强制垃圾收集周期纠正的情况下声明“我死了” 我们的想法是为阈值选择一个足够大的值,使

我注意到,有时,当内存几乎耗尽时,GC试图以任何性能代价完成(导致程序几乎冻结,有时几分钟),而不是立即抛出OOME(OutOfMemoryError)

有没有办法在这方面调整GC


将程序速度降至接近零会使其无响应。在某些情况下,最好有一个响应“我死了”而不是根本没有响应。

我不知道有什么方法可以按照您描述的方式配置Java垃圾收集器

一种方法可能是让应用程序主动监控可用内存量,例如使用,并在低于某个阈值且无法通过强制垃圾收集周期纠正的情况下声明“我死了”


我们的想法是为阈值选择一个足够大的值,使流程永远不会进入您描述的情况。

我强烈建议不要这样做,Java尝试GC而不是立即抛出OutOfMemoryException更有意义——除非已经用尽了所有选择,否则不要让应用程序崩溃

如果您的应用程序内存不足,您应该增加最大堆大小,或者查看它在内存分配方面的性能,看看它是否可以优化

需要注意的是:

  • 如果在其他地方不引用对象,则在不需要对象的位置使用弱引用
  • 不要分配比您需要的更大的对象(即当您在阵列生命周期中只需要访问其中三个对象时,请存储一个包含100个对象的庞大阵列),或者当您只需要存储八个值时,请使用长数据类型
  • 不要将对对象的引用保留得太长
编辑:我想你误解了我的观点。如果您意外地留下了一个对不再需要使用的对象的活动引用,它显然仍然不会被垃圾收集。这与空值无关,只是以防万一——这方面的一个典型示例是将大型对象用于特定目的,但当它超出范围时,它不是GC,因为活动引用意外地留在了其他地方,而您不知道会导致泄漏。一个典型的例子是哈希表查找,它可以用弱引用来解决,因为只有弱可达时才有资格使用GC


不管怎样,这些只是我头脑中关于如何通过内存分配提高性能的一般想法。我想指出的一点是,询问如何更快地抛出OutOfMemory错误,而不是让Java GC尝试最好释放堆上的空间,这不是一个好主意。相反,优化您的应用程序。

类似于您所追求的东西是内置在最近的JVM中的

如果你:

  • 正在使用来自(至少)Java 6的Hotspot VM
  • 正在使用并行或并发垃圾收集器
  • 启用选项
    usegcoveredlimit
    (默认情况下,对于这些采集器,该选项处于启用状态,因此,如果尚未禁用该选项,则更具体地说是启用该选项)

然后,在实际耗尽内存之前,您将得到一个OOM:如果最近98%以上的时间都花在GC中恢复那么,事实证明,自Java8 b92以来,有一个解决方案:

-XX:+ExitOnOutOfMemoryError

启用此选项时,JVM将在第一次出现内存不足错误时退出。如果您希望重新启动JVM实例而不是处理内存不足错误,可以使用它

-XX:+CrashOnOutOfMemoryError

如果启用此选项,当发生内存不足错误时,JVM崩溃并生成文本和二进制崩溃文件(如果启用了核心文件)

一个好主意是将上述选项之一与良好的旧
-XX:+HeapDumpOnOutOfMemoryError

我测试了这些选项,它们实际上按照预期工作

链接


JVM中的
错误是失败的。如果没有错误,JVM为什么要抛出错误(OOME)?如果您关心性能,那么在尝试微调GC之前,您可能应该确保JVM有足够的内存来完成其工作。要么添加更便宜的RAM,要么追踪正在消耗所有内存的内存泄漏……您必须小心使用
catch
esofoome的代码。因为它是一个可以随时抛出的
virtualmachineeexception
(不仅仅是新
的结果),当您捕获它时,您的对象可能处于一致状态。请参见-1,因为前面的答案准确地解释了如何微调GC@AngelO'Sphere:谢谢你花时间解释投票失败的原因。但是,请注意,“上一个”答案已经贴在我的后面了。oki,为了公平起见,我再次添加了a+1;然而,“如果您不知道”现代JVM的选项,您可能应该限制发布。主动监控,例如,需要经常在线程中执行,这本身可能又是一个减速原因。。。(哎呀,无法解开-1)@Angel O'Sphere:不用担心。为了每个人的利益,我认为最好是我们都集中精力做出建设性的贡献,而不是去评论其他人的努力。。。您似乎不知道GC是如何工作的,这意味着weakreference无论如何都不会有帮助,只会增加内存足迹。你的“不要保留参考资料”声明也是如此。。。在“以防万一”中取消某些内容是没有必要的,事实上,这样做是GC的一个常见误解;你被侮辱了,我让你屈服并解释了原因?哦,我的另一个