0

我已经通过 Akka(端点)使用 Camel 的 Jetty 组件实现了一个 Web 服务,它将接收到的消息转发到具有以下设置的参与者池:

   def receive = _route()
   def lowerBound = 5
   def upperBound = 20
   def rampupRate = 0.1
   def partialFill = true
   def selectionCount = 1
   def instance() = Actor.actorOf[Processor]

而Processor是一个处理接收到的消息并以处理结果进行回复的类。该应用程序一直在我的本地计算机上正常运行且完美无缺,但是在将其部署在 EC2 微型实例(512m 内存 - 类似 CentOS 的操作系统)上后,操作系统(oom-killer)由于 OutOfMemory(不是 JVM OOM)而终止了进程30个左右的电话(不管电话的频率如何)。

在本地分析应用程序不会显示任何显着的内存泄漏(如果存在的话)。由于一些困难,我无法在远程机器上执行正确的分析,但监视“top”的输出,我观察到一些有趣的事情,即应用程序初始化后可用的可用内存保持在 400mb 左右,之后它在 380mb 到 400mb 之间反弹,这似乎很自然(gc等)。但有趣的是,在接到第 30 个左右的电话后,它突然从那里变成了 5mb 的可用内存,然后砰的一声,它被杀死了。/var/log/messages 中的 oom-killer 日志验证这已由操作系统完成,因为缺少内存/空闲交换。

现在这并不是完全与 Akka 相关,但经过 3 天的无望摔跤后,我终于决定向你们寻求一些建议。

感谢任何线索。

4

2 回答 2

1

我的一般观察是 JVM 使用了 Java 堆之外的大量内存。我不知道确切的原因,但只能推测它可能使用普通的 C 堆进行编译或编译代码存储或其他 permgen 东西或诸如此类的东西。不管怎样,我发现很难控制它的使用。

除非您对磁盘存储压力很大,否则您可能只想创建一个 1 或 2 GB 的交换文件,以便 JVM 有一些溢出的地方。以我的经验,它在 Java 堆之外使用的内存无论如何都不会被过度引用,并且可以安全地换出而不会引起太多 I/O。

于 2014-02-01T19:39:12.600 回答
1

我观察到,当创建了许多应该立即进行垃圾收集的小对象时,Java 进程就会被杀死。可能是因为在临时对象被 GC 回收之前达到了内存限制。

尝试使用并发标记和清除垃圾收集器运行它:

java -XX:+UseConcMarkSweepGC
于 2014-02-01T19:34:24.430 回答