2011-08-23 1 views
0

je l'ai mis en place un service Web en utilisant la composante jetée de Camel par Akka (point final) qui transmet les messages reçus à un pool d'acteur avec la configuration de:processus JVM tué par OS

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

Et processeur est une classe traite le message reçu et répond avec le résultat du processus. L'application a fonctionné normalement et sans faille sur ma machine locale, mais après l'avoir déployée sur une micro-instance EC2 (512m de mémoire - CentOS comme OS) l'OS (oom-killer) tue le processus en raison de OutOfMemory (pas JVM OOM) 30 appels ou plus (quelle que soit la fréquence des appels).

Le profilage local de l'application n'indique aucune fuite de mémoire significative, s'il en existe. En raison de certaines difficultés je ne pouvais pas effectuer correctement le profilage sur la machine distante mais en surveillant la sortie "top", j'ai observé quelque chose d'intéressant: la mémoire disponible reste autour de 400mb après l'initialisation de l'application, ensuite elle rebondit entre 380mb et 400mb assez naturel (gc, etc). Mais la partie intéressante est que, après avoir reçu le 30e appel, il va soudainement à partir de là à 5 Mo de mémoire libre et de boom, il est tué. Le journal oom-killer dans/var/log/messages vérifie que cela a été fait par le système d'exploitation en raison du manque de mémoire/échange libre.

Maintenant, ce n'est pas tout à fait pertinent, mais Akka-je finalement décidé que je devais demander des conseils de vous les gars, après 3 jours de lutte sans espoir.

Merci pour les pistes.

+0

Avez-vous essayé de réduire la taille du tas JVM? –

+0

Oui, je lui ai fixé une limite dure de 64m, mais étrangement, il est encore tué avant d'atteindre la limite de la JVM. Peut-être que je devrais essayer des quantités plus faibles? – parsa

Répondre

1

J'ai observé que lorsque beaucoup de petits objets sont créés, ce qui devrait être immédiatement recueilli les déchets, le processus Java est tué. Peut-être parce que la limite de mémoire est atteinte avant que les objets temporaires soient récupérés par GC.

ESSAYEZ en cours d'exécution avec la marque concurrente et de balayage garbage collector:

java -XX:+UseConcMarkSweepGC 
1

Mon observation générale est que la machine virtuelle Java utilise beaucoup de mémoire au-delà du tas Java. Je ne sais pas exactement pour quoi, mais je peux seulement spéculer qu'il pourrait utiliser le tas C normal pour la compilation ou le stockage de code compilé ou d'autres trucs permgen ou autres joyeusetés. De toute façon, j'ai trouvé difficile de contrôler son utilisation.

Sauf si vous êtes très pressé sur le stockage de disque, vous pouvez simplement créer un fichier d'échange d'un Go ou deux pour que la machine virtuelle Java a un endroit à déborder. Dans mon expérience, la mémoire qu'il utilise en dehors du tas Java n'est pas souvent référencée trop souvent et peut tout simplement s'évaporer en toute sécurité sans causer beaucoup d'E/S.

Questions connexes