{"id":1267,"date":"2021-06-14T12:42:30","date_gmt":"2021-06-14T10:42:30","guid":{"rendered":"https:\/\/www.loicmathieu.fr\/wordpress\/?p=1267"},"modified":"2021-06-14T14:57:24","modified_gmt":"2021-06-14T12:57:24","slug":"debugger-une-image-native-graalvm-avec-gdb","status":"publish","type":"post","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/debugger-une-image-native-graalvm-avec-gdb\/","title":{"rendered":"Debugger une image native GraalVM avec GDB"},"content":{"rendered":"<p>Dans un pr\u00e9c\u00e9dent article, j&rsquo;avais \u00e9voqu\u00e9 <a href=\"https:\/\/www.loicmathieu.fr\/wordpress\/informatique\/profiler-une-image-native-graalvm-avec-perf\/\" rel=\"noopener\" target=\"_blank\">comment profiler une image native GraalVM avec perf<\/a>. Si vous ne connaissez pas l&rsquo;outil GraalVM et les limitations qu&rsquo;il apporte, je vous conseille de relire mon article, ou tout du moins son d\u00e9but.<\/p>\n<p>Comme vu dans mon article pr\u00e9c\u00e9dent, une image native va contenir une JVM minimaliste, appel\u00e9e SubstrateVM, qui ne supporte pas JVM-TI, et ne permet donc pas l&rsquo;utilisation de debugger Java. Pour d\u00e9bugger une image native, il faut donc un debugger syst\u00e8me (OS-level), je vous propose ici d&rsquo;utiliser <a href=\"https:\/\/www.gnu.org\/software\/gdb\/\" rel=\"noopener\" target=\"_blank\">GDB &#8211; The GNU Project Debugger<\/a> qui fonctionne sur la plupart des distributions Linux ainsi que MacOS.<\/p>\n<p>Tout d&rsquo;abord, nous allons cr\u00e9er un projet Hello World Quarkus avec la commande Maven suivante :<\/p>\n<pre>\nmvn io.quarkus:quarkus-maven-plugin:1.13.4.Final:create \\\n    -DprojectGroupId=fr.loicmathieu.quarkus.debug \\\n    -DprojectArtifactId=helloworld-debug \\\n    -DclassName=\"fr.loicmathieu.quarkus.debug.GreetingResource\" \\\n    -Dpath=\"\/hello\"\n<\/pre>\n<p>Puis, nous allons modifier la classe <code>GreetingResource<\/code> pour qu&rsquo;elle prenne en param\u00e8tre le nom de la personne \u00e0 qui dire <em>Hello<\/em> :<\/p>\n<pre>\n@Path(\"\/hello\")\npublic class GreetingResource {\n\n    @GET\n    @Produces(MediaType.TEXT_PLAIN)\n    public String hello(@QueryParam(\"name\") String name) {\n        return \"Hello \" + (name == null ? \"World\" : name);\n    }\n}\n<\/pre>\n<p>Vous pouvez alors lancer l&rsquo;application via <code>mvn quarkus:dev<\/code>, et la tester via <code>curl localhost:8080\/hello\/myself<\/code>.<\/p>\n<p>Nous allons maintenant packager l&rsquo;application en une image native, en incluant les symboles de debug pour que notre debugger puisse les trouver. Pour cela il faut utiliser la commande suivant : <code>mvn package -Pnative -Dquarkus.native.debug.enabled=true -DskipTests<\/code>.<\/p>\n<ul><li><code>-Pnative<\/code> : indique \u00e0 Maven d&rsquo;utiliser le profil <code>native<\/code> qui indique au plugin Maven Quarkus de g\u00e9n\u00e9rer une image native de votre application. Le plugin Quarkus s&rsquo;occupera de tout pour vous (et entre autre de g\u00e9n\u00e9rer la tr\u00e8s longue ligne de commande de l&rsquo;outil <strong>native-image<\/strong>).<\/li>\n\n<li><code>quarkus.native.debug.enabled=true<\/code> : option de configuration qui active les fonctionnalit\u00e9s de debug des applications natives. Permet d&rsquo;inclure les symboles de debug dans l&rsquo;image native. Pour plus d&rsquo;informations sur les symboles de debug avec l&rsquo;outils native image : <a href=\"https:\/\/www.graalvm.org\/reference-manual\/native-image\/DebugInfo\/\" rel=\"noopener\" target=\"_blank\">DebugInfo<\/a><\/li>\n\n<li><code>-DskipTests<\/code> : on ne lance pas les tests car comme on a modifi\u00e9 le code de la ressource mais pas les tests, ils ne marcheront pas<\/li>\n<\/ul>\n<p>Si tout se passe bien, au bout d&rsquo;une minute et quelques, vous aurez votre image native dans le r\u00e9pertoire <code>target<\/code>. Mais avant de le lancer en mode debug, il nous faut copier les sources de nos librairies pour que GDB puisse y acc\u00e9der (les sources de votre code sont d\u00e9j\u00e0 disponibles pour GDB).\nPour cela on peut utiliser la commande Maven suivante : <code>mvn dependency:sources<\/code>.<\/p>\n<p>Si tout s&rsquo;est bien pass\u00e9, vous aurez dans le r\u00e9pertoire <code>target<\/code> les r\u00e9pertoires et fichiers suivants :<\/p>\n<ul><li><code>helloworld-debug-1.0.0-SNAPSHOT-runner<\/code> : l&rsquo;image native de votre application<\/li>\n\n<li><code>helloworld-debug-1.0.0-SNAPSHOT-runner.debug<\/code> : les symboles de debug<\/li>\n\n<li><code>sources<\/code> : le r\u00e9pertoire de source de l&rsquo;application et des librairies tierces<\/li>\n<\/ul>\n<p>Sur Linux ou MacOS, si vous n&rsquo;avez pas le fichier <code>helloworld-debug-1.0.0-SNAPSHOT-runner.debug<\/code>, c&rsquo;est parce qu&rsquo;il vous manque le package binutils. Les symboles de debug seront alors int\u00e9gr\u00e9s \u00e0 l&rsquo;image native.<\/p>\n<p>Sur les distributions classiques Linux, vous pouvez facilement installer GDB depuis les repos de votre distribution. Sous Ubuntu, c&rsquo;est aussi simple qu&rsquo;un <code>sudo apt-get install gdb<\/code>.<\/p>\n<p>Pour lancer votre application en mode debug, positionnez-vous dans le r\u00e9pertoire <code>target<\/code> puis ex\u00e9cutez <code>gdb helloworld-debug-1.0.0-SNAPSHOT-runner<\/code>. GDB va automatiquement d\u00e9tecter les symboles de votre application ainsi que les sources, car nous utilisons les fichiers et r\u00e9pertoires par d\u00e9faut.<\/p>\n<p>A ce stade, votre application n&rsquo;est pas encore lanc\u00e9e. Avant de la lancer, nous allons mettre un point d&rsquo;arr\u00eat (breakpoint) en entr\u00e9e de la m\u00e9thode de notre ressource, pour pouvoir la debugger via <code>break GreetingResource.java:1<\/code>. Cela va mettre un breakpoint \u00e0 la premi\u00e8re ligne d&rsquo;instruction de votre classe.<\/p>\n<p>Puis nous pouvons lancer l&rsquo;application via <code>run&amp;<\/code>, le <code>&amp;<\/code> permet de rendre la main au shell de GDB (tapez sur entr\u00e9e si vous ne voyez pas l&rsquo;invite du shell de GDB).<\/p>\n<p>A ce stade, l&rsquo;application est lanc\u00e9e, nous pouvons l&rsquo;utiliser. Vous pouvez appeler votre endpoint via votre navigateur, ou un curl dans un shell externe. GDB permet m\u00eame d&rsquo;appeler une commande shell directement depuis son propre shell via <code>shell curl localhost:8080\/hello?name=me &amp;<\/code>.<\/p>\n<p>Vous devez normalement avoir dans le shell de GDB un message comme quoi le point d&rsquo;arr\u00eat a \u00e9t\u00e9 atteint :<\/p>\n<pre>\nThread 31 \"ecutor-thread-2\" hit Breakpoint 1, fr.loicmathieu.quarkus.debug.GreetingResource.hello(java.lang.String)(void) () at fr\/loicmathieu\/quarkus\/debug\/GreetingResource.java:15\n15          return \"Hello \" + (name == null ? \"World\" : name);\n<\/pre>\n<p>Maintenant, on va lancer quelques commandes pour debugger notre application.<\/p>\n<p>Pour voir la valeur d&rsquo;une variable on va utiliser <code>print<\/code>.<\/p>\n<pre>\n(gdb) print name\n$6 = '\\000' \n<\/pre>\n<p>H\u00e9las, les cha\u00eenes de caract\u00e8res sont vues comme des tableaux de char, et GDB nous en affiche le premier \u00e9l\u00e9ment. Ce n&rsquo;est pas tr\u00e8s utile ici.<\/p>\n<p>Pour voir ce que sont en train de faire les threads de l&rsquo;application, tapez <code>info threads<\/code>. Vous aurez alors une sortie comme suit.<\/p>\n<pre>\n  Id   Target Id                                            Frame \n  1    Thread 0x7ffff7d6f2c0 (LWP 154724) \"helloworld-debu\" futex_wait_cancelable (private=, expected=0, futex_word=0x2223dfc) at ..\/sysdeps\/nptl\/futex-internal.h:183\n  2    Thread 0x7ffff6bff640 (LWP 154729) \"gnal Dispatcher\" futex_abstimed_wait_cancelable (private=0, abstime=0x0, clockid=0, expected=0, futex_word=0x221c060 )\n    at ..\/sysdeps\/nptl\/futex-internal.h:320\n  4    Thread 0x7ffff55ff640 (LWP 154731) \"ecutor-thread-1\" futex_abstimed_wait_cancelable (private=, abstime=0x7ffff55fec78, clockid=-178263168, expected=0, futex_word=0x7fffe8000dac)\n    at ..\/sysdeps\/nptl\/futex-internal.h:320\n  5    Thread 0x7ffff4bff640 (LWP 154732) \"-thread-checker\" futex_abstimed_wait_cancelable (private=, abstime=0x7ffff4bfebe8, clockid=-188749072, expected=0, futex_word=0x7fffec000da8)\n    at ..\/sysdeps\/nptl\/futex-internal.h:320\n  6    Thread 0x7fffe7fff640 (LWP 154733) \"ntloop-thread-0\" 0x00007ffff7e8956e in epoll_wait (epfd=9, events=0x2227f90, maxevents=1024, timeout=-1) at ..\/sysdeps\/unix\/sysv\/linux\/epoll_wait.c:30\n  7    Thread 0x7fffe75ff640 (LWP 154734) \"ntloop-thread-1\" 0x00007ffff7e8956e in epoll_wait (epfd=12, events=0x222afa0, maxevents=1024, timeout=-1) at ..\/sysdeps\/unix\/sysv\/linux\/epoll_wait.c:30\n  8    Thread 0x7fffe6dfe640 (LWP 154735) \"ntloop-thread-2\" 0x00007ffff7e8956e in epoll_wait (epfd=15, events=0x222dfb0, maxevents=1024, timeout=1800000) at ..\/sysdeps\/unix\/sysv\/linux\/epoll_wait.c:30\n  9    Thread 0x7fffe61ff640 (LWP 154736) \"ntloop-thread-3\" 0x00007ffff7e8956e in epoll_wait (epfd=18, events=0x2230fc0, maxevents=1024, timeout=-1) at ..\/sysdeps\/unix\/sysv\/linux\/epoll_wait.c:30\n  10   Thread 0x7fffe57ff640 (LWP 154737) \"ntloop-thread-4\" 0x00007ffff7e8956e in epoll_wait (epfd=21, events=0x2233fd0, maxevents=1024, timeout=-1) at ..\/sysdeps\/unix\/sysv\/linux\/epoll_wait.c:30\n[...]\n<\/pre>\n<p>La commande <code>backtrace<\/code> vous permet de r\u00e9cup\u00e9rer la stack d&rsquo;appel du point d&rsquo;arr\u00eat :<\/p>\n<pre>\n#0  fr.loicmathieu.quarkus.debug.GreetingResource.hello(java.lang.String)(void) () at fr\/loicmathieu\/quarkus\/debug\/GreetingResource.java:15\n#1  0x00000000004e1300 in com.oracle.svm.reflect.GreetingResource_hello_ff2c07ee54b83f7b7e9993013704c94177591f6c_119.invoke(java.lang.Object, java.lang.Object[])(void) ()\n    at com\/oracle\/svm\/core\/graal\/snippets\/TypeSnippets.java:75\n#2  0x0000000000f04dd7 in org.jboss.resteasy.core.MethodInjectorImpl.invoke(org.jboss.resteasy.spi.HttpRequest, org.jboss.resteasy.spi.HttpResponse, java.lang.Object, java.lang.Object[])(void) ()\n    at java\/lang\/reflect\/Method.java:566\n#3  0x0000000000f048fa in org.jboss.resteasy.core.MethodInjectorImpl.invoke(org.jboss.resteasy.spi.HttpRequest, org.jboss.resteasy.spi.HttpResponse, java.lang.Object)(void) ()\n    at org\/jboss\/resteasy\/core\/MethodInjectorImpl.java:130\n#4  0x0000000000f11cdd in org.jboss.resteasy.core.ResourceMethodInvoker.internalInvokeOnTarget(org.jboss.resteasy.spi.HttpRequest, org.jboss.resteasy.spi.HttpResponse, java.lang.Object)(void) ()\n    at org\/jboss\/resteasy\/core\/ResourceMethodInvoker.java:660\n#5  0x0000000000f129e3 in org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTargetAfterFilter(org.jboss.resteasy.spi.HttpRequest, org.jboss.resteasy.spi.HttpResponse, java.lang.Object)(void) ()\n    at org\/jboss\/resteasy\/core\/ResourceMethodInvoker.java:524\n#6  0x0000000000f103b8 in org.jboss.resteasy.core.ResourceMethodInvoker..Lambda.1337\/1751592192.get(void) ()\n#7  0x0000000000f2c557 in org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(void) ()\n    at org\/jboss\/resteasy\/core\/interception\/jaxrs\/PreMatchContainerRequestContext.java:364\n#8  0x0000000000f126d0 in org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(org.jboss.resteasy.spi.HttpRequest, org.jboss.resteasy.spi.HttpResponse, java.lang.Object)(void) ()\n    at org\/jboss\/resteasy\/core\/ResourceMethodInvoker.java:476\n#9  0x0000000000f123a9 in org.jboss.resteasy.core.ResourceMethodInvoker.invoke(org.jboss.resteasy.spi.HttpRequest, org.jboss.resteasy.spi.HttpResponse, java.lang.Object)(void) ()\n    at org\/jboss\/resteasy\/core\/ResourceMethodInvoker.java:433\n#10 0x0000000000f121a5 in org.jboss.resteasy.core.ResourceMethodInvoker.invoke(org.jboss.resteasy.spi.HttpRequest, org.jboss.resteasy.spi.HttpResponse)(void) ()\n    at org\/jboss\/resteasy\/core\/ResourceMethodInvoker.java:402\n#11 0x0000000000f2381c in org.jboss.resteasy.core.SynchronousDispatcher.invoke(org.jboss.resteasy.spi.HttpRequest, org.jboss.resteasy.spi.HttpResponse, org.jboss.resteasy.spi.ResourceInvoker)(void) ()\n    at org\/jboss\/resteasy\/core\/ResourceMethodInvoker.java:69\n#12 0x0000000000f23d90 in org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(org.jboss.resteasy.spi.HttpRequest, org.jboss.resteasy.spi.HttpResponse)(void) ()\n    at org\/jboss\/resteasy\/core\/SynchronousDispatcher.java:261\n[...]\n<\/pre>\n<p>Vous pouvez ensuite utiliser la commande <code>step<\/code> pour aller \u00e0 l&rsquo;instruction suivante, et <code>continue&amp;<\/code> pour aller au point d&rsquo;arr\u00eat suivant.<\/p>\n<p>Quand votre session de debug est finie, vous pouvez quitter GDB avec <code>quit<\/code>.<\/p>\n<p>Si on reprend l&rsquo;int\u00e9gralit\u00e9 des commandes lanc\u00e9e, \u00e7a donne \u00e7a :<\/p>\n<pre>\n(gdb) break GreetingResource.java:1\nBreakpoint 1 at 0x5158d0: file fr\/loicmathieu\/quarkus\/debug\/GreetingResource.java, line 15.\n(gdb) run&amp;\nStarting program: \/data\/dev\/helloworld-debug\/target\/helloworld-debug-1.0.0-SNAPSHOT-runner \n(gdb) [Thread debugging using libthread_db enabled]\nUsing host libthread_db library \"\/lib\/x86_64-linux-gnu\/libthread_db.so.1\".\n[New Thread 0x7ffff6bff640 (LWP 154729)]\n[New Thread 0x7ffff61ff640 (LWP 154730)]\n[Thread 0x7ffff61ff640 (LWP 154730) exited]\n[...]\n__  ____  __  _____   ___  __ ____  ______ \n --\/ __ \\\/ \/ \/ \/ _ | \/ _ \\\/ \/\/_\/ \/ \/ \/ __\/ \n -\/ \/_\/ \/ \/_\/ \/ __ |\/ , _\/ ,&lt; \/ \/_\/ \/\\ \\   \n--\\___\\_\\____\/_\/ |_\/_\/|_\/_\/|_|\\____\/___\/   \n2021-05-27 12:45:05,992 INFO  [io.quarkus] (main) helloworld-debug 1.0.0-SNAPSHOT native (powered by Quarkus 1.13.4.Final) started in 0.064s. Listening on: http:\/\/0.0.0.0:8080\n2021-05-27 12:45:05,999 INFO  [io.quarkus] (main) Profile prod activated. \n2021-05-27 12:45:05,999 INFO  [io.quarkus] (main) Installed features: [cdi, resteasy]\n(gdb) shell curl localhost:8080\/hello?name=me &amp;\n(gdb) \nThread 31 &quot;ecutor-thread-2&quot; hit Breakpoint 1, fr.loicmathieu.quarkus.debug.GreetingResource.hello(java.lang.String)(void) () at fr\/loicmathieu\/quarkus\/debug\/GreetingResource.java:15\n15          return &quot;Hello &quot; + (name == null ? &quot;World&quot; : name);\n(gdb) print name\n$6 = &#039;\\000&#039; \n(gdb) info threads\n  Id   Target Id                                            Frame \n  1    Thread 0x7ffff7d6f2c0 (LWP 154724) &quot;helloworld-debu&quot; futex_wait_cancelable (private=, expected=0, futex_word=0x2223dfc) at ..\/sysdeps\/nptl\/futex-internal.h:183\n  2    Thread 0x7ffff6bff640 (LWP 154729) &quot;gnal Dispatcher&quot; futex_abstimed_wait_cancelable (private=0, abstime=0x0, clockid=0, expected=0, futex_word=0x221c060 )\n    at ..\/sysdeps\/nptl\/futex-internal.h:320\n  4    Thread 0x7ffff55ff640 (LWP 154731) &quot;ecutor-thread-1&quot; futex_abstimed_wait_cancelable (private=, abstime=0x7ffff55fec78, clockid=-178263168, expected=0, futex_word=0x7fffe8000dac)\n    at ..\/sysdeps\/nptl\/futex-internal.h:320\n[...]\n(gdb) backtrace\n#0  fr.loicmathieu.quarkus.debug.GreetingResource.hello(java.lang.String)(void) () at fr\/loicmathieu\/quarkus\/debug\/GreetingResource.java:15\n#1  0x00000000004e1300 in com.oracle.svm.reflect.GreetingResource_hello_ff2c07ee54b83f7b7e9993013704c94177591f6c_119.invoke(java.lang.Object, java.lang.Object[])(void) ()\n    at com\/oracle\/svm\/core\/graal\/snippets\/TypeSnippets.java:75\n#2  0x0000000000f04dd7 in org.jboss.resteasy.core.MethodInjectorImpl.invoke(org.jboss.resteasy.spi.HttpRequest, org.jboss.resteasy.spi.HttpResponse, java.lang.Object, java.lang.Object[])(void) ()\n    at java\/lang\/reflect\/Method.java:566\n#3  0x0000000000f048fa in org.jboss.resteasy.core.MethodInjectorImpl.invoke(org.jboss.resteasy.spi.HttpRequest, org.jboss.resteasy.spi.HttpResponse, java.lang.Object)(void) ()\n    at org\/jboss\/resteasy\/core\/MethodInjectorImpl.java:130\n[...]\n(gdb) step\n[Thread 0x7ffff55ff640 (LWP 154731) exited]\n[New Thread 0x7ffff61ff640 (LWP 154825)]\n[Switching to Thread 0x7ffff61ff640 (LWP 154825)]\n\nThread 32 &quot;ecutor-thread-3&quot; hit Breakpoint 1, fr.loicmathieu.quarkus.debug.GreetingResource.hello(java.lang.String)(void) () at fr\/loicmathieu\/quarkus\/debug\/GreetingResource.java:15\n15          return &quot;Hello &quot; + (name == null ? &quot;World&quot; : name);\n(gdb) step\nHello mejava.lang.String.valueOf(java.lang.Object)(void) () at java\/lang\/String.java:2951\n2951            return (obj == null) ? &quot;null&quot; : obj.toString();\n(gdb) continue&amp;\nContinuing.\n(gdb) Hello me\n(gdb) quit\n<\/pre>\n<p>Pour conclure, m\u00eame si debugger en ligne de commande n&rsquo;est pas forc\u00e9ment tr\u00e8s pratique, GDB nous permet d&rsquo;avoir une vue sur l\u2019ex\u00e9cution interne de notre application quand elle est packag\u00e9e comme une image native relativement facilement. C&rsquo;est un outil int\u00e9ressant \u00e0 avoir dans sa bo\u00eete \u00e0 outils.<\/p>","protected":false},"excerpt":{"rendered":"<p>Dans un pr\u00e9c\u00e9dent article, j&rsquo;avais \u00e9voqu\u00e9 comment profiler une image native GraalVM avec perf. Si vous ne connaissez pas l&rsquo;outil GraalVM et les limitations qu&rsquo;il apporte, je vous conseille de relire mon article, ou tout du moins son d\u00e9but. Comme vu dans mon article pr\u00e9c\u00e9dent, une image native va contenir une JVM minimaliste, appel\u00e9e SubstrateVM, qui ne supporte pas JVM-TI, et ne permet donc pas l&rsquo;utilisation de debugger Java. Pour d\u00e9bugger une image native, il faut donc un debugger syst\u00e8me&#8230;<p class=\"read-more\"><a class=\"btn btn-default\" href=\"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/debugger-une-image-native-graalvm-avec-gdb\/\">Lire la suite<span class=\"screen-reader-text\"> Lire la suite<\/span><\/a><\/p><\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"activitypub_content_warning":"","activitypub_content_visibility":"","activitypub_max_image_attachments":4,"activitypub_interaction_policy_quote":"anyone","activitypub_status":"","footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[9],"tags":[],"class_list":["post-1267","post","type-post","status-publish","format-standard","hentry","category-informatique"],"aioseo_notices":[],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"jetpack-related-posts":[{"id":1090,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/quarkus-jlink-et-application-class-data-sharing-appcds\/","url_meta":{"origin":1267,"position":0},"title":"Quarkus, jlink et Application Class Data Sharing (AppCDS)","author":"admin","date":"vendredi 29 mai 2020","format":false,"excerpt":"Quarkus est optimis\u00e9 pour d\u00e9marrer rapidement et avoir une empreinte m\u00e9moire tr\u00e8s faible. Ceci est vrai en d\u00e9ployant dans une JVM standard mais encore plus en d\u00e9ployant notre application comme un ex\u00e9cutable natif via GraalVM. Quarkus facilite grandement la cr\u00e9ation d\u2019ex\u00e9cutable natif, gr\u00e2ce \u00e0 \u00e7a, une application Quarkus d\u00e9marre en\u2026","rel":"","context":"Dans &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/category\/informatique\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/quarkus_metrics_graphic_bootmem_wide-1024x473.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/quarkus_metrics_graphic_bootmem_wide-1024x473.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/quarkus_metrics_graphic_bootmem_wide-1024x473.png?resize=525%2C300&ssl=1 1.5x"},"classes":[]},{"id":1153,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/profiler-une-image-native-graalvm-avec-perf\/","url_meta":{"origin":1267,"position":1},"title":"Profiler une image native GraalVM avec perf","author":"admin","date":"lundi 16 novembre 2020","format":false,"excerpt":"L'outil GraalVM native-image permet de g\u00e9n\u00e9rer un ex\u00e9cutable natif (ou image native) depuis votre application Java. Cet ex\u00e9cutable natif va d\u00e9marrer tr\u00e8s rapidement et avoir une empreinte m\u00e9moire beaucoup plus faible qu'une application Java traditionnelle; au prix de performances en pic r\u00e9duites et d'un temps de cr\u00e9ation de ce package\u2026","rel":"","context":"Dans &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/category\/informatique\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/flamegraph-2.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/flamegraph-2.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/flamegraph-2.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/flamegraph-2.png?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":1353,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/quarkus-tip-comment-ne-pas-creer-une-extension-quarkus\/","url_meta":{"origin":1267,"position":2},"title":"Quarkus Tip : Comment NE PAS cr\u00e9er une extension Quarkus","author":"admin","date":"mardi 16 novembre 2021","format":false,"excerpt":"Quand on d\u00e9veloppe une application compos\u00e9e de plusieurs composants, il est fr\u00e9quent de vouloir partager du code dans une librairie externe, par exemple via un JAR externe int\u00e9gr\u00e9 comme une d\u00e9pendance de vos composants. Quarkus est un framework d'extension, chaque extension qu'il propose permet d'int\u00e9grer une technologie (client BDD, framework\u2026","rel":"","context":"Dans &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1672,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/devoxx-fr-2023-improving-your-skills-with-the-debugger-par-bouke-nijuis\/","url_meta":{"origin":1267,"position":3},"title":"Devoxx FR 2023 &#8211; Improving your skills with the Debugger par Bouke Nijuis","author":"admin","date":"vendredi 14 avril 2023","format":false,"excerpt":"Deuxi\u00e8me conf\u00e9rence \u00e0 laquelle j'assiste (et derni\u00e8re pour laquelle j'ai pris des notes), \u00e7a parle de l'utilisation du debugger. On va utiliser un programme simple de type Hello World. Apr\u00e8s un rapide rappel sur les bases de l'utilisation d'un debugger avec IntelliJ on entre dans le vif du sujet, les\u2026","rel":"","context":"Dans &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":923,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/devoxx-france-2019\/","url_meta":{"origin":1267,"position":4},"title":"Devoxx France 2019","author":"admin","date":"lundi 13 mai 2019","format":false,"excerpt":"Cette ann\u00e9e, j'ai eu la chance d'assister \u00e0 Devoxx France, j'ai m\u00eame eu la chance d'\u00eatre speaker et de donner deux talks (Mes premiers pas en deeplearning avec Keras et Arthas - Alibaba Java Diagnostic Tool ), mais \u00e7a je vous en parlerais plus tard ;) Voici un petit compte\u2026","rel":"","context":"Dans &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1668,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/devoxx-fr-2023-hidden-security-features-of-th-jvm-everything-you-didnt-know-and-more-par-steve-poole\/","url_meta":{"origin":1267,"position":5},"title":"Devoxx FR 2023 &#8211; Hidden security features of the JVM &#8211; everything you didn&rsquo;t know and more par Steve Poole","author":"admin","date":"vendredi 14 avril 2023","format":false,"excerpt":"Premi\u00e8re conf\u00e9rence \u00e0 laquelle je vais pour cette session de Devoxx France parle de s\u00e9curit\u00e9 dans le JVM par Steve Poole. Le Security Manager est d\u00e9pr\u00e9ci\u00e9 mais la JVM a un design fantastique pour la s\u00e9curit\u00e9. Tout d'abord, pourquoi se soucier de la s\u00e9curit\u00e9 ? Premi\u00e8re conf\u00e9rence \u00e0 laquelle je\u2026","rel":"","context":"Dans &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/posts\/1267","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/comments?post=1267"}],"version-history":[{"count":0,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/posts\/1267\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/media?parent=1267"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/categories?post=1267"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/tags?post=1267"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}