我正在用AppDynamics监视一个生产系统,我们只是让系统慢到爬行,几乎冻结了。就在这个事件之前,AppDynamics显示了所有GC活动(小的和大同的),几个minutes...and的平行线,然后恢复活力。
即使在系统的超低负载期间,我们仍然看到我们的JVM在执行一些GC活动。我们从来没有得到完全持平,并下降到0。
另外-网络I/O与GC/内存平行线在相同的时间实例中平行线。
所以我问:系统级别的东西会导致JVM冻结,还是导致它的垃圾收集挂起/冻结?这是在一台CentOS机器上。
发布于 2013-04-19 08:00:01
您的操作系统是否启用了交换。
我注意到Java一旦在启用交换功能的情况下填满操作系统上的所有内存,就会出现巨大的问题--它实际上会偏离状态窗口系统,有效地锁定它们并导致重新启动。
我的理论是:
起初,它对系统的影响不大,但如果你试图启动一个需要大量内存的应用程序,它可能需要很长时间,而你的系统却一直在退化。
多个大型VM会使这种情况更糟,我运行3或4个大型VM,当我获得超过60%-70%的RAM使用量时,我的系统就开始运转起来。
这是猜测,但它描述了我经过几天的测试后所看到的行为。
其效果是,所有的交换似乎是“防止”gc。更准确地说,操作系统正在花费大部分GC时间交换,这使它看起来像是在GC期间什么都不做。
将-Xmx设置为较低的值,直到允许有足够的空间以避免交换为止.这总是解决了我的问题,如果它不能解决你的问题,那么我对你问题的原因就错了:)
发布于 2013-04-19 07:49:57
如果没有更多的信息,就很难找到问题的确切原因。
但我可以试着回答你的问题
操作系统能阻止垃圾收集吗?
这与操作系统阻止线程垃圾收集器并让其他线程运行是不太可能的。你不应该那样调查。
操作系统能阻止JVM吗?
是的,它可以完成很多任务,但是速度比你想象的要快,以至于所有的进程都在同时运行。
jvm和其他进程一样,在操作系统的控制下运行。您必须在应用程序挂起时检查它所使用的cpu (在服务器上监视,而不是在jvm中)。如果这个数字很低,我就会看到两个原因(但还有更多):
发布于 2013-04-19 07:59:28
理论上说,是的,可以。但它会练习,永远也不应该。
在大多数Java虚拟机中,应用程序线程并不是唯一正在运行的线程。除了应用程序线程之外,还有编译线程、终结器线程、垃圾收集线程等等。为这些线程和机器上运行的其他程序中的其他线程分配CPU核心的调度决策基于许多参数(线程优先级、最后执行时间等),这些参数对所有线程都是公平的。因此,在实践中,系统中的任何线程都不应该在不合理的长时间内等待CPU的分配,并且操作系统不应该在无限的时间内阻塞任何线程。
垃圾收集线程(和其他VM线程)需要做的活动很少。他们需要定期检查是否需要垃圾收集。即使应用程序线程全部挂起,也可能有其他VM线程(如JIT编译器线程或终结器线程)工作,从而分配对象和触发垃圾收集。对于在Java中实现VM线程而不是在C/C++中实现VM线程的元循环JVM尤其如此;
此外,大多数现代JVM使用分代垃圾收集器(将堆划分为单独的空间并将具有不同年龄的对象放置在堆的不同部分的垃圾收集器),这意味着随着对象越来越老,它们需要移动到其他旧空间。因此,即使不需要收集对象,分代垃圾收集器也可以将对象从一个空间移动到另一个空间。
当然,每个垃圾收集器的细节与JVM不同。为了在伤害上添加更多的盐,一些JVM支持不止一种类型的垃圾收集器。但是,在空闲应用程序中看到最小的垃圾收集活动并不令人惊讶。
https://stackoverflow.com/questions/16090702
复制