Conseils pour garder Perl utilisation de la mémoire faible
Quels sont les bons conseils pour garder la mémoire d'utilisation de la basse dans un script Perl? Je suis intéressé à apprendre comment garder ma mémoire, aussi bas que possible pour les systèmes selon les programmes Perl. Je sais que Perl n'est pas génial quand il s'agit de l'utilisation de la mémoire, mais je voudrais savoir si il y a des conseils pour l'améliorer.
Alors, que pouvez-vous faire pour garder un script Perl qui utilise moins de mémoire. Je suis intéressé par toutes les suggestions, s'ils sont réels conseils pour l'écriture de code, ou des conseils pour savoir comment compiler Perl différemment.
Modifier pour Bounty:
J'ai un programme en perl qui sert de serveur pour une application réseau. Chaque client qui se connecte à elle obtienne sa propre processus enfant actuellement. J'ai utilisé les threads au lieu de fourches ainsi, mais je n'ai pas été en mesure de déterminer si l'utilisation de threads au lieu de fourche est en fait plus efficace en terme de mémoire.
Je voudrais essayer de l'utilisation de threads au lieu de fourchettes de nouveau. Je crois en théorie, il devrait enregistrer sur l'utilisation de la mémoire. J'ai quelques questions à cet égard:
- Ne threads créés en Perl empêcher la copie des bibliothèques de modules Perl
en mémoire pour chaque thread? - Est fils (fils) le moyen le plus efficace (ou la seule)
façon de créer des threads en Perl? - Dans les fils, je peux spécifier un stack_size paramater, qu'est-ce spécifiquement
dois-je considérer lors de la spécification de cette valeur, et quelle est son incidence
l'utilisation de la mémoire?
Avec les threads en Perl/Linux, ce qui est la méthode la plus fiable pour déterminer le montant réel de l'utilisation de la mémoire sur une base par thread?
- C'est une très vaste question. Les conseils peuvent être moins aléatoire si vous pouvez fournir certaines tâches que vous voulez accomplir.
- Je pense que vous devriez sortir de votre questions supplémentaires dans de nouveaux Stackoverflow questions.
- Ouais j'avais pensé que permettrait d'obtenir une meilleure réponse, mais j'ai réalisé qu'après que j'ai d'installation de la bounty. Maintenant, je ne suis pas sûr de savoir comment j'allais faire de si. Est-il possible d'annuler un bounty? Je ne pense pas que ça :-/
- Notez que les "fils" ne crée pas ce que les gens normalement appeler "fils" en dehors de Perl: "utiliser des threads" émule un processus normal, et est généralement beaucoup plus lent, et plus que réel threads ou processus réels, par exemple, "fils" émule le MMU dans le logiciel et le rend plus ou moins complète des copies physiques de chaque thread qui crée un nouveau thread.
- pour perl meilleure prise en charge est de fourche. les threads en perl sont comme des étrangers. il y a beaucoup de bugs, des conditions de course ou les serrures. spécialement, si vous utilisez dans le thread travailleur fourche, les opérations d'e/S et les tuyaux. Il ya une grande chance, votre fil raccrocher, et vous en tant que solution de contournement doit détacher. Il n'est pas vrai, la nature de threads en perl est avec du fil de l'émulation par la fourche. Généralement sur linux threads sont très proches de processus. Il devrait économiser de la mémoire, mais pas en perl. Lorsque vous permettra de créer des threads en perl, toutes les variables seront dupliqués comme une copie de fil. Ensuite, une meilleure utilisation de la fourche et de sélectionner les fonctions.
Vous devez vous connecter pour publier un commentaire.
Quel type de problème vous êtes en cours d'exécution, et que signifie "grand" signifie pour vous? J'ai des amis, vous devez charger 200 Go de fichiers en mémoire, de sorte que leur idée de bons conseils est très différent que le budget shopper pour un minimum de VM tranches de souffrance avec 250 Mo de RAM (vraiment? Mon téléphone a plus que cela).
En général, Perl, tient toute la mémoire que vous utilisez, même si il ne l'utilise pas. Réaliser que l'optimisation de la dans une direction, par exemple la mémoire, pourrait avoir un impact négatif de l'autre, comme la vitesse.
Ce n'est pas une liste exhaustive (et il y a de plus en Programmation Perl):
☹ Utiliser Perl le profilage de la mémoire d'outils pour vous aider à trouver les zones à problème. Voir Le profilage des tas utilisation de la mémoire sur les programmes perl et Comment trouver la quantité de mémoire physique occupé par une table de hachage en Perl?
☹ Utiliser des variables lexicales avec le plus petit périmètre possible afin de permettre à Perl pour la ré-utilisation de la mémoire lorsque vous n'en avez pas besoin.
☹ Éviter de créer de grandes structures temporaires. Par exemple, la lecture d'un fichier avec un
foreach
lit toutes les entrées à la fois. Si vous avez seulement besoin d'elle, ligne par ligne, dewhile
.☹ Vous pourriez même pas besoin d'avoir le fichier en mémoire. Carte mémoire les fichiers au lieu d'aspirer eux
☹ Si vous avez besoin pour créer des structures de données, pensez à quelque chose comme DBM::Deep ou d'autres moteurs de stockage pour garder la plupart de la mémoire vive et sur le disque jusqu'à ce que vous en avez besoin.
☹ Ne pas laisser les gens utiliser votre programme. Chaque fois que je l'ai fait, j'ai réduit l'empreinte mémoire d'environ 100%. Il réduit également sur les demandes de support.
☹ Passer de gros morceaux de texte et de grands agrégats de référence afin de ne pas faire une copie, ainsi stocker deux fois la même information. Si vous avez à le copier parce que vous voulez changer quelque chose, vous pourriez être coincé. Cela va dans les deux sens comme sous-routine arguments et les valeurs de retour de sous-routine:
☹ Traquer les fuites de mémoire dans les modules. J'ai eu de gros problèmes avec une application jusqu'à ce que j'ai réalisé que un module n'était pas la libération de la mémoire. J'ai trouvé un patch dans le module de la RT file d'attente, appliqué, et résolu le problème.
☹ Si vous avez besoin de gérer un gros morceau de données une fois, mais ne veulent pas de la persistance de la mémoire, de confier les travaux à un processus enfant. Le processus de l'enfant a seulement l'empreinte mémoire pendant qu'il tourne. Lorsque vous obtenez la réponse, le processus de l'enfant s'arrête et la libère de la mémoire. De même, le travail des systèmes de distribution de Gearman, peut se propager de travail entre les machines.
☹ Tour récursive des solutions dans itératif ceux. Perl n'a pas de queue à la récursivité d'optimisation, de sorte que chaque nouveau téléphone, qui s'ajoute à la pile d'appel. Vous pouvez optimiser la queue problème vous-même avec des astuces avec goto ou d'un module, mais c'est beaucoup de travail pour accrocher une technique que vous n'avez probablement pas besoin.
☹ N'a-t-il 6 Go ou seulement cinq? Eh bien, pour vous dire la vérité, dans toute cette excitation j'ai un peu perdu la trace de moi-même. Mais comme c'est du Perl, le plus puissant de la langue dans le monde, et pourrait faire exploser votre propre mémoire, vous avez obtenu de vous poser une question: j'ai de la chance? Eh bien, pensez-ay, le punk?
Il ya beaucoup plus, mais il est trop tôt dans la matinée pour comprendre ce que ceux qui sont. Je couvre certains en Mastering Perl et Efficace De Programmation Perl.
perl -E '$|++;while(1){ my $h = {}; say $h; sleep 1}'
. Encore une fois c'est plus un argument pour les variables lexicales qu'à l'encontre de la mémoire accaparer. Si votre programme de jamais revendications beaucoup de mémoire à la fois, il va le garder pour la fin.Mes deux dimes.
Ne threads créés en Perl empêcher la copie module Perl bibliothèques en mémoire pour chaque thread?
avoir sa propre.
Est fils (fils) le moyen le plus efficace (ou la seule) façon de créer des threads en Perl?
Dans les fils, je peux spécifier un stack_size paramater, que doit-je considérer lors de l'
la spécification de cette valeur, et quelle est son incidence sur l'utilisation de la mémoire?
raconte pthreads à quelle distance ils devraient être les uns des autres. Chaque fois qu'une fonction est appelée
les variables locales sont allouées sur la pile. Si la taille de la pile des limites de profondeur de manière récursive.
vous pouvez allouer aussi peu que possible de l'étendre que votre application fonctionne toujours.
Avec les threads en Perl/Linux, ce qui est la méthode la plus fiable pour déterminer le montant réel de l'utilisation de la mémoire
sur une base par thread?
Si vous êtes vraiment désespéré, vous pourriez essayer de monter la mémoire comme un système de fichiers (tmpfs/ramdisk) et de lire/écrire/supprimer des fichiers sur elle. Je suppose que le tmpfs mise en œuvre est assez intelligent pour libérer de la mémoire lorsque vous supprimez un fichier.
Vous pouvez également mmap (voir Fichier::Map, Sys::Mmap) un énorme fichier sur le tmpfs, une idée que j'ai eu de Cache::FastMmap.
Jamais essayé, mais cela devrait fonctionner 🙂
En plus de brian d foy les suggestions, j'ai trouvé le suivant aussi BEAUCOUP aidé.
Brian mentionne l'utilisation de variables lexicales avec le plus petit de la portée. Si vous êtes à la bifurcation, à l'aide de "undef" permet également de par immédiatement libérer de la mémoire pour Perl pour le ré-utiliser. Vous déclarez donc un scalaire, tableau, hachage ou même des sous, et lorsque vous avez terminé, utilisez :
ma (@divs) = localtime(time);
$VAR{minute} = $divs[1];
le fnud @divs;
le fnud @tableau;
undef $scalaire;
le fnud %hash;
le fnud &sous;
Et ne pas utiliser n'importe quel unnecssary variables pour rendre votre code plus petits. Il est préférable de coder tout ce qui est possible pour réduire l'espace de noms d'utilisation.
Puis, il y a un tas d'autres trucs que vous pouvez essayer selon les fonctionnalités de votre application. Le nôtre a été exécuté par cron toutes les minutes. Nous avons constaté que nous pourrions fourche à la moitié du processus avec un sleep(30), de sorte moitié exécuter et terminer dans les 30 premières secondes, libérant ainsi de la cpu et de la mémoire, et l'autre moitié de courir après un délai de 30 secondes. Réduit de moitié l'utilisation des ressources à nouveau. Tous, nous avons réussi à réduire l'utilisation de la RAM de plus de 2 GO en bas à 200 mo, une économie de 90%.
Nous avons réussi à obtenir une assez bonne idée de l'utilisation de la mémoire avec
que notre script a été exécuté sur une relativement stable serveur avec un seul site. Donc, regarder "ram libre" nous a donné une assez bonne indication de memery utilisation.
Aussi "ps" grepping pour votre script, et si fourches, de tri, soit par la mémoire ou de l'utilisation de l'uc a été d'une bonne aide.
Les deux fils et la fourche sera CoW (Copy on Write) pages de mémoire. Avec les threads, vous pouvez défini des variables partagées, mais par défaut de copie vos variables par sujet. Dans les deux cas, vous pouvez vous attendre à une plus grande utilisation de la mémoire.
Je ne sais pas exactement quel type de demande que vous faites affaire avec, mais vous pouvez envisager d'écrire votre Application à l'aide Événement Piloté par le modèle au lieu de Parent/Enfant de processus. Je vous recommande de prendre un coup d'oeil à AnyEvent c'est assez simple, et compte tenu de l'application devient thread unique ( ou processus ), vous allez économiser de la mémoire (et encore plus vite dans certains cas). Les gens même écrit des serveurs avec AnyEvent avec de très bonnes performances et vous pourriez presque pas remarqué qu'il est mono-thread. Jetez un oeil par exemple à Twiggy
Essayez d'utiliser plus de la mise en cache. La logique de la mise en œuvre de la mise en cache de routine est toujours la même, de sorte que vous pouvez automatiser à l'aide de module CPAN Memoize. Utilisation Devel::Taille pour vérifier la quantité de mémoire.