我们有一个Linux服务器,可以启动大约20个java程序.这些java程序都是相同的,除了它们使用的是不同的端口.这些程序运行良好.然而,过了一段时间,所有20个程序都在同一时间崩溃.这些程序中的每一个都分配了2 gig的内存,通过这样启动它们:
java -jar -Xmx 2000m
然而,据我们所知,这些节目并没有使用这些数量的记忆.整个系统有4 gig的内存.
那么,问题是,java程序可能会导致所有其他9个程序崩溃吗?VM是否共享,以便在崩溃时,所有java程序都崩溃了?是否有一个日志文件我可以检查java崩溃的原因?java输出没有显示任何错误.
编辑:奇怪的是,这发生在更长的时间后,如3小时.这20个进程已经运行了相当长的一段时间,然后突然全部崩溃了.如果java运行时为每个程序启动它自己的进程,为什么它们都会崩溃?
很难准确地说出为什么java进程同时都在退出.甚至不清楚为什么他们要死了.为了诊断这些问题,我会:
转一些GC记录; 例如,添加"-verbose:gc"命令行选项,
确保应用程序捕获并记录可能会杀死"主"线程的异常,以及
查看进程当前目录,看看它们是否正在离开崩溃转储.
但独立于此,当您运行java -jar -Xmx2000m ...20次时,您正在查看20个OS进程,每个进程可能使用超过2Gb的虚拟内存.在具有4Gb物理内存的机器上,这简直太疯狂了.即使你有足够的交换空间(40Gb或更多)来支持那么多的虚拟内存,你也可能会在堆积到达那么大的地方之前导致虚拟内存抖动.当系统开始颠簸时,系统性能将会下降.
为避免这种情况,您需要确保系统上所有活动进程的总虚拟需求不会超过您拥有的物理内存.减少Java进程的数量,减少最大堆大小或两者.(请记住,JVM也使用非堆内存.)
您应该考虑的另一件事是重新架构您的系统,以便它在一个JVM中使用多线程而不是使用多个JVM.如果正确实现,您应该能够在多线程体系结构中获得更多吞吐量,因为:
这避免了拥有代码和公共数据结构的多个副本,因此对于有用的堆对象,您有相对更多的内存,
多线程体系结构中的线程可以共享先前获取的对象的缓存,先前计算的值等
单个大堆的GC比许多小堆更高效,
如果系统只有4GB内存,你显然无法为20个进程中的每个进程分配2GB内存.即使我的水晶球现在无法访问您的日志文件,我也会假设整个系统内存不足,导致大多数正在运行的进程几乎同时崩溃.
| 归档时间: |
|
| 查看次数: |
3963 次 |
| 最近记录: |