Bonjour à tous.
Je sèche sur un problème de CPU...
J'ai un service Windows créé avec Delphi qui fonctionne correctement pendant quelques jours (3 à 4 jours), et soudain pour une raison inconnue, l'utilisation du CPU devient assez importante.
Ce phénomène n’est pas généralisé sur tous les postes sur lesquels le service est installé.
Voici une capture qui montre l’état de mon service avant :
Voici une capture de son état après quelques jours de fonctionnement :
But de mon service :
Le service est destiné à enregistrer les connexions entre un programme et un serveur SQL.
Le programme envoie une demande au service et reçoit en retour une réponse du service.
De plus le service gère le contenu d'un petit fichier local.
Technique utilisée :
Pour recevoir et répondre à la demande, j’utilise le composant « TIdTCPServer », l’événement OnExecute se charge de traiter la demande ainsi :
La demande vient sous un format xml crypté, elle est stockée dans un objet dédié « TXMLCmd ».
Rien de bien méchant...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70 procedure TdmServiceServer.IdTCPServerExecute(AContext: TIdContext); var CommandData : string; Command : TXMLCmd; Response : TXMLCmd; begin try CommandData := AContext.Connection.Socket.ReadLn; except on E : Exception do begin if (E is EIdSilentException) then CommandData := EmptyStr else raise; end; end; if (CommandData <> EmptyStr) then begin // Chaque demande est exécutée dans un thread séparé, il faut initialiser // COM pour pouvoir utiliser XML CoInitializeEx(nil, COINIT_MULTITHREADED); try Command := TXMLCmd.Create; Command.XMLText := Uncrypt(CommandData); Response := TXMLCmd.Create; try Response.CMDId := Command.CMDId; Response.CMDName := Command.CMDName; try case Command.CMDId of CMD_CONNECT_ID : begin ExecConnect(Command, Response); end; CMD_COMP_SUB_CONNECT_ID : begin ExecCompSubConnect(Command, Response); end; CMD_DISCONNECT_ID : begin ExecDisconnect(Command, Response); end; CMD_GET_SQL_CONNECTION_DATA_ID : begin ExecGetSQLConnectionData(Command, Response); end; . . . else // Commande invalide Response.CMDId := CMD_ERROR_ID; Response.CMDName := CMD_ERROR_NAME; Response.ParamAsString['Message'] := Format(rsInvalidCommand, [Command.CMDName]); end; AContext.Connection.Socket.WriteLn(Crypt(Response.XMLText)); finally Response.Free; end; finally Command.Free; end; finally CoUnInitialize; end; end; end;
Mis à part quelques boucles "for", rien de spécial, rien qui bloque son fonctionnement, mais une consommation CPU étrange.
Après toutes une série d'analyses, de log, je tombe sur un élément suspect, les « threads » utilisés.
Au démarrage du service, les threads sont au nombre de 8. Ensuite, ce nombre monte et redescend de 8 à 9 à 8. Mais à un certain moment, ce nombre de threads monte et ne redescend pas…
Par exemple, dans ma deuxième image, le nombre de Threads est à 11 et le CPU à 33.
J'ai commencé à m'intéresser à ces Threads, mais c'est un sujet que je ne maîtrise pas vraiment.
Dans Delphi, après avoir attaché le service depuis Delphi, j'ai une liste de Threads qui ressemble à ça :
Du coup, je voulais essayer d'identifier ce que font ces Threads.
Mais comment ?
Il y a la colonne "Location", comment je peux savoir quelle est le code attaché derrière cette info ?
Ensuite, vu que ces "Threads" semblent augmenter, y a t-il un moyen depuis Delphi, à l'intérieure de ma programmation du service, de lister ces threads et de connaître le code exécuté ?
Merci.
Partager