44 votes

Existe-t-il un moyen d'accélérer la Javadoc (prend 7 minutes) ?

Je suis en train de construire une Javadoc pour un module avec 2.509 classes. Cela prend actuellement 7 minutes, soit 6 fichiers par seconde.

J'ai essayé

mvn -T 1C install

Cependant javadoc n'utilise qu'une seule unité centrale. Existe-t-il un moyen d'en utiliser davantage et/ou de l'accélérer ?

J'utilise Mise à jour Oracle JDK 8 112 . Ma machine de développement a 16 cœurs et 128 Go de mémoire.

En lançant l'enregistreur de vol, je constate qu'il n'y a qu'un seul fil. main

enter image description here

Pour les personnes intéressées, j'ai utilisé les options suivantes :

<plugin>
    <artifactId>maven-javadoc-plugin</artifactId>
    <configuration>
        <additionalJOptions>
            <additionalJOption>-J-XX:+UnlockCommercialFeatures</additionalJOption>
            <additionalJOption>-J-XX:+FlightRecorder</additionalJOption>
            <additionalJOption>-J-XX:StartFlightRecording=name=test,filename=/tmp/myrecording-50.jfr,dumponexit=true</additionalJOption>
            <additionalJOption>-J-XX:FlightRecorderOptions=loglevel=debug</additionalJOption>
        </additionalJOptions>
    </configuration>
</plugin>

REMARQUE : une solution de contournement consiste à faire :

-Dmaven.javadoc.skip=true

0 votes

Profil du processus javadoc. Je suppose que c'est probablement lié aux entrées-sorties. Vous pourriez donc charger la source sur un ramdisk ou un ssd.

0 votes

@ElliottFrisch Une bonne idée, le disque est occupé à 3%, mais le CPU est presque exactement à 100% (un seul cpu). Je peux le profiler avec Flight Recorder cependant, je mettrai à jour.

0 votes

L'unité centrale peut être en attente d'IO et à 100%.

6voto

lbndev Points 378

Si vous avez un projet multi-modules, il construira au mieux le javadoc de chaque module en parallèle (si votre graphe de dépendance entre les modules le permet).

Le processus javadoc lui-même est monotâche, de sorte que vous ne pourrez pas utiliser plusieurs cœurs pour générer le javadoc d'un seul module.

Cependant, étant donné que vous avez beaucoup de classes (et peut-être beaucoup de doclets @link ou similaires ?), peut-être que le processus javadoc pourrait bénéficier d'un tas étendu. Avez-vous examiné l'activité du GC ? Essayez d'ajouter ceci dans votre configuration, voyez si cela vous aide :

<additionalJOption>-J-Xms2g</additionalJOption>
<additionalJOption>-J-Xmx2g</additionalJOption>

0 votes

J'ai pu vérifier que la taille de la mémoire n'est pas limitée. La valeur par défaut devrait être de 32 Go sur cette machine.

0 votes

@PeterLawrey le problème n'est peut-être pas les limites, mais la taille de départ. La JVM n'étend un peu la mémoire qu'après chaque GC complet, donc une quantité raisonnable de Xms permettra à la JVM d'éviter trop de GC avant d'étendre suffisamment la mémoire pour votre charge de travail.

5voto

df778899 Points 21

@lbndev a raison, au moins avec le Doclet par défaut ( com.sun.tools.doclets.formats.html.HtmlDoclet ) qui est fournie avec la Javadoc. Un coup d'œil sur le code source confirme l'implémentation d'un seul thread :

(Ces liens renvoient aux sources du JDK 8. Avec le JDK 11, les classes ont été déplacées, mais la base for boucles en HtmlDoclet y AbstractDoclet sont toujours là).

Certains profils basés sur des échantillons ont confirmé que ces méthodes constituaient un goulot d'étranglement : Javadoc-profiling

Ce ne sera pas ce que vous espériez entendre, mais il semble qu'il n'y ait pas d'option dans la Javadoc standard actuelle pour le multithreading, au moins dans un seul module Maven.

generateClassFiles() etc. se prêteraient bien à un peu de multithreading, bien qu'il faille probablement modifier le JDK. Comme mentionné ci-dessous AbstractDoclet.isValidDoclet() bloque même activement la sous-classification des HtmlDoclet . Essayer de réimplémenter certaines de ces boucles en tant que tiers nécessiterait d'intégrer un grand nombre d'autres codes.

Un examen d'autres implémentations de Doclet (par ex. javadown ) n'a trouvé qu'un style d'implémentation similaire autour de l'exploration des paquets et des classes. Il est possible que d'autres personnes sur ce fil de discussion en sachent plus.

Si l'on réfléchit un peu plus largement, il est possible de trouver des solutions autour de DocFileFactory . Elle est clairement identifiée comme une classe interne (elle n'est même pas publique dans le paquet), mais elle fait abstraction de l'écriture des fichiers (HTML). Il semble possible qu'une version alternative de ce programme puisse mettre en mémoire tampon le HTML, ou l'envoyer directement vers un fichier zip, afin d'améliorer les performances IO. Mais il est clair que cela nécessiterait également de comprendre le risque de changement dans les outils du JDK.

0 votes

Hmmm, une sous-classe astucieuse de HtmlDoclet pourraient être remplacées, comme par exemple generateClassFiles() et de désigner un exécuteur testamentaire. Il devra cependant être spécifique au JDK. Puis-je vérifier quel JDK est la cible maintenant ?

0 votes

Bonne chance avec cela, avec tous les singletons, les classes avec état, etc. y javac. C'est inutile.

0 votes

Eh bien ... l'idée était d'intervenir plus tard avec une nouvelle implémentation de doclet - comme le -doclet paramètre. Il semble que les responsables de la mise en œuvre de HtmlDoclet a vu cette possibilité et l'a verrouillée. AbstractDoclet.isValidDoclet() vérifie que le nom de classe complet de la sous-classe est com.sun.tools.doclets.formats.html.HtmlDoclet . Elle est privée et appelée à partir d'une méthode interne, il y aurait donc beaucoup de choses à réimplémenter. Semblable dans le JDK 11.

0voto

Jonathan Gibbons Points 626

Javadoc, et le doclet standard, sont actuellement fondamentalement mono-thread.

Il est prévu d'améliorer cette situation, principalement en générant des pages en parallèle, mais cela implique d'adapter la sécurité de la MT à diverses structures de données partagées.

0voto

Arun Avanathan Points 360

Vous pouvez demander à Maven d'utiliser plusieurs threads par cœur dans tous les cœurs.

Par exemple.

mvn -T 4C install # will use 4 threads per available CPU core

Vous pouvez modifier 4 ci-dessus à la valeur de votre choix. Vous avez une machine avec beaucoup de ressources. Essayez 8 ou 16 .

Avez-vous également essayé d'utiliser javadoc-no-fork ? Cela permettra de s'assurer que la javadoc n'est pas déclenchée une deuxième fois - https://maven.apache.org/plugins/maven-javadoc-plugin/examples/javadoc-nofork.html

0 votes

Cela ne change pas le fonctionnement du plugin javadoc.

1 votes

J'ai ajouté des informations sur javadoc-no-fork

0 votes

Cela vaut la peine d'essayer.

0voto

Mumrah81 Points 1427

La personnalisation de Maven est un moyen d'accélérer la génération de javadoc.

Une autre approche consisterait à modifier le doclet utilisé pour générer la javadoc. Le plugin javadoc de maven vous permet de changer le doclet utilisé pour générer le javadoc.

https://maven.apache.org/plugins/maven-javadoc-plugin/examples/alternate-doclet.html

J'ai trouvé la doclet commerciale suivante (je ne suis en aucun cas affilié à eux) qui prétend être plus rapide que la javadoc traditionnelle. Il propose une licence gratuite/essai/commerciale. Si vous êtes vraiment désireux d'accélérer votre construction de javadoc, cela vaut peut-être la peine de regarder si le prix en vaut la peine.

http://www.filigris.com/docflex-javadoc

Il existe peut-être des alternatives opensource sur internet...

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X