OVH Cloud OVH Cloud

Serveurs dll contenant plusieurs objets

3 réponses
Avatar
Guy Lafrenière
Bonjour Collègues!

Je sais que je peux créer plusieurs objets différents avec un même serveur
dll. Il suffit d'y inclure plusieurs classes publiques. J'ai besoin de créer
différents objets qui n'ont pas de relation logique entre eux. Je trouverais
plus pratique de créer un seul serveur dll. Ça m'éviterait de devoir gérer
plusieurs projets de programmation. Ce serveur constituerait une sorte de
bibliothèque générale d'objets.

Ma question concerne les performances et l'espace mémoire occupé. Si
j'inclus plusieurs classes dans le même serveur, quand je crée un objet,
est-ce seulement le code requis pour cet objet qui est chargé en mémoire, ou
est-ce tout le code du serveur dll, y compris les classes, forms et modules
de code qui ne servent que pour la création des autres objets?

Autrement dit, quels sont les pour et les contre d'inclure dans un même
serveur dll plusieurs objets qui ont peu ou pas de rapport logique entre
eux?

Je repose la même question pour un serveur exe, si la réponse est
différente.

Merci à l'avance pour toute réponse.


Guy Lafrenière

3 réponses

Avatar
Patrick Philippot
Bonjour,

Autrement dit, quels sont les pour et les contre d'inclure dans un
même serveur dll plusieurs objets qui ont peu ou pas de rapport
logique entre eux?



Il faut considérer les choses d'un point de vue physique et d'un point
de vue conception.

Aspect mécanique
-----------------------

Pour vous aider à prendre la décision, il convient peut-être de revenir
sur la notion de "chargement en mémoire". Beaucoup de développeurs
pensent que le lancement d'un Exe ou le chargement d'une DLL passent par
le chargement intégral de la totalité du code en mémoire. Ce n'est pas
du tout ce qui se passe.

Quand Windows charge un module (exe ou dll), il crée un File Mapping.
C'est à dire une correspondance entre un fichier sur le disque et une
zone mémoire réservée à ce mapping. Pour simplifier, l'image du fichier
est vue en mémoire comme un tableau d'octets de la taille du fichier.
Mais çà ne veut pas dire que des pages de mémoire physique sont
automatiquement et immédiatement attribuée à chaque zone correspondante
du fichier. Les pages de mémoire physique sont réservées mais uniquement
commitées (physiquement allouées) quand on a besoin d'accéder au code
(ou aux données) qui devraient s'y trouver et qui n'y sont pas encore.

C'est exactement sur ce principe que fonctionne la mémoire virtuelle du
système, à ceci près qu'au lieu de faire le mapping sur un fichier image
exe ou dll, le système fait le mapping sur le fichier de pagination. Ce
mécanisme connu sous le nom de MMF (Fichiers Mappés en Mémoire) peut
d'ailleurs être utilisé dans vos propres applications pour manipuler
facilement de très gros fichiers.

Partant de là, quand on dit qu'un programme de 1 MB est "chargé" en
mémoire, cela veut simplement dire que le mapping a été créé et que les
premières pages de code indispensables au démarrage de l'application ont
effectivement été commitées. Mais cela ne signifie pas que 1 MB de code
ont été chargé d'un seul tenant en mémoire physique.

Ensuite le commit et le decommit (pagination d'une page de mémoire
physique vers le disque) se font au fur et à mesure des besoins de
l'application et de l'occupation de la mémoire physique par cette
application et les autres. L'onglet Performance du task Manager donnent
quelques indications sur cet état.

Donc, si le code de votre composant est organisé de telle manière qu'il
n'y ait pas de couplage entre les différents serveurs (c-à-d que le code
de l'un ne fasse pas appel systématiquement au code de l'autre), la
charge mémoire va s'organiser de telle manière que le "working set" du
processus maintienne en mémoire physique le code qui est effectivement
utilisé et que le code non encore utilisé ou rarement utilisé passe
rapidement en mémoire paginée. Il est certain que statistiquement, il y
a plus de chances que le code d'un serveur n'ont utilisé se retrouve
présent en mémoire physique que s'il était dans une DLL séparée mais
dans la pratique, on verra rarement une différence marquée, encore une
fois si l'indépendance des différents serveurs est réelle.

Idem pour les exe.

Aspect conception
-----------------------

Ceci étant posé, le fait de confiner dans un même composant des classes
qui n'ont aucune relation logique entre elles n'est peut-être pas une
excellente idée. Cela peut compliquer sensiblement les problèmes de
distribution, de sécurité et de maintenance. En général, on stocke dans
un même composant, des classes dont les activités ont une relation
fonctionnelle évidente. Avec le temps, on risque également de créer du
couplage entre ces serveurs en leur faisant partager le code de routines
internes par exemple. Le fait d'avoir plusieurs serveurs dans un même
projet peut également provoquer cette dérive (utilisation mal venue -
quand est-elle bienvenue? - du trop fameux mot-clé Friend par exemple).

Au final, je prêche plutôt pour un juste équilibre entre découpage trop
fin et regroupement dangereux dans un module unique. Regroupez mais par
thème.

--
Patrick Philippot - Microsoft MVP
MainSoft Consulting Services
www.mainsoft.fr
Avatar
Jean-Marc
"Guy Lafrenière" a écrit dans le message de
news:evV$
Bonjour Collègues!



Hello !

Je sais que je peux créer plusieurs objets différents avec un même


serveur
dll. Il suffit d'y inclure plusieurs classes publiques. J'ai besoin de


créer
différents objets qui n'ont pas de relation logique entre eux. Je


trouverais
plus pratique de créer un seul serveur dll. Ça m'éviterait de devoir


gérer
plusieurs projets de programmation. Ce serveur constituerait une sorte


de
bibliothèque générale d'objets.



C'est une très bonne idée.

Ma question concerne les performances et l'espace mémoire occupé. Si
j'inclus plusieurs classes dans le même serveur, quand je crée un


objet,
est-ce seulement le code requis pour cet objet qui est chargé en


mémoire, ou
est-ce tout le code du serveur dll, y compris les classes, forms et


modules
de code qui ne servent que pour la création des autres objets?



D'après mon expérience, n'est chargé que ce qui est utilisé,
plus les dépendances si il y en a.

Autrement dit, quels sont les pour et les contre d'inclure dans un


même
serveur dll plusieurs objets qui ont peu ou pas de rapport logique


entre
eux?



Tout dépend du nombre de fonctions, d'objets, etc. Si ils sont sans
rapport
direct mais quand même utiles au sein d'un même projet, et que leur
nombre
reste petit, faire une seule dll se défend, à mon avis.

Si en revanche dans la dll on commence à avoir des dizaines de fonctions
pour plusieurs objets, alors ça peut valoir le coup de regrouper un peu,
ne serait ce que parce que ça sera plus léger à maintenir, même si de
fait
ça te fait gérer plusieurs projets.

Je repose la même question pour un serveur exe, si la réponse est
différente.




Pour conclure:
- Si tout petit projet, moins de N(*) fonctions, objets, classes,
alors bof, ok pour une seule Dll.
- Si plus de N(*) fonctions ou objets, alors autant faire propre et
créer
plusieurs dll.

(*) Une valeur raisonnable de N pourrait être 10.


--
Jean-marc
Tester mon serveur (VB6) => http://myjmnhome.dyndns.org
"There are only 10 kind of people
those who understand binary and those who don't."
mailto: remove '_no_spam_' ;
Avatar
Guy Lafrenière
Bonjour Collègues!

Je remercie Patrick et Jean-Marc d'avoir pris le temps de me répondre.

La réponse de Patrick est beaucoup trop technique pour mon niveau, mais elle
est sûrement utile pour les programmeurs avancés. J'en comprend que le choix
ne se fait pas entre tout charger le code du serveur dll ou ne charger que
la partie utilisée. C'est beaucoup plus complexe.

Jean-Marc me rassure. Le serveur que je veux créer contiendra peu d'objets.
Il s'agit d'objets que j'utilise dans chacun de mes projets: objet
Utilisateur avec LoginForm, objet Erreur avec ErrorMsgForm, objet
SplashScreen, etc. En les regroupant dans un même serveur je me facilite la
vie et je comprend de vos deux réponses que la pénalité côté performance
sera négligeable.

Merci et au revoir!

Guy Lafrenière