دستورات JDK

در این مقاله، با تعدادی از دستورات مفید و پرکاربرد JDK آشنا میشوید.
jps: چاپ JVMهای در حال اجرا
برای نمایش لیست JVMهای در حال اجرا، میتوانید از دستور jps استفاده کنید. این دستور در جاوا 6 معرفی شده است.
jps
به صورت پیشفرض، صرفا PID و نام ساده کلاس راهاندازیکننده (یا نام JAR راهاندازیشده) را نمایش میدهد.
560 Jps 99714 spring-petclinic-2.0.0.BUILD-SNAPSHOT.jar 95689 CommandServer
البته تعدادی پارامتر اختیاری هم وجود دارد که با استفاده از آنها میتوانید اطلاعات بیشتری کسب کنید.
پارامتر | کارکرد |
l- | نمایش نام کامل کلاس (fully-qualified)، مسیر کامل فایل JAR |
v- | نمایش آرگومانهای استفادهشده در راهاندازی JVM مانند Dxxx- |
m- | نمایش پارامترهای دادهشده به اپلیکیشن. مانند args در متد (main(String… args |
با توجه به وضعیت سیستم، با فعال بودن تمام پارامترهای بالا، چنین خروجیای حاصل خواهد شد:
99714 target/spring-petclinic-2.0.0.BUILD-SNAPSHOT.jar 679 sun.tools.jps.Jps -lvm -Xms8m \ -Dapplication.home=/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home 95689 org.asciidoctor.diagram.CommandServer -Djava.awt.headless=true
jinfo: چاپ دادههای راهاندازیشده بر روی JVM
برای حل مشکلات production، نیاز است که به یکسری اطلاعات اضافی در خصوص یک JVM خاصِ در حال اجرا دسترسی داشته باشیم. این اطلاعات شامل مجموعهای از تمام flagها و آرگومانهای JVM و همچنین propertyهای سیستم است.
به این منظور، میتوانید از دستور jinfo استفاده کنید و به اطلاعات تنظیمات جاوا برای یک فرآیند جاوایی خاص دست بیابید.
jinfo 95689
یک نمونه خروجی مربوط به این دستور را در ادامه مشاهده میکنید (جهت افزایش خوانایی، کمی خلاصه و فرمت شده است):
Java System Properties: #Fri Dec 07 16:22:25 CET 2018 gopherProxySet=false awt.toolkit=sun.lwawt.macosx.LWCToolkit java.specification.version=11 sun.cpu.isalist= sun.jnu.encoding=UTF-8 ... java.class.version=55.0 socksNonProxyHosts=local|*.local|169.254/16|*.169.254/16 VM Flags: -XX:CICompilerCount=3 -XX:ConcGCThreads=1 -XX:G1ConcRefinementThreads=4 -XX:G1HeapRegionSize=1048576 -XX:GCDrainStackTargetSize=64 -XX:InitialHeapSize=268435456 -XX:MarkStackSize=4194304 -XX:MaxHeapSize=4294967296 -XX:MaxNewSize=2576351232 -XX:MinHeapDeltaBytes=1048576 -XX:NonNMethodCodeHeapSize=5830092 -XX:NonProfiledCodeHeapSize=122914074 -XX:ProfiledCodeHeapSize=122914074 -XX:ReservedCodeCacheSize=251658240 -XX:+SegmentedCodeCache -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseG1GC VM Arguments: jvm_args: -Djava.awt.headless=true java_command: org.asciidoctor.diagram.CommandServer java_class_path (initial): ~/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/asciidoctor-diagram-1.5.9/lib/server-1.3.13.jar: ~/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/asciidoctor-diagram-1.5.9/lib/ditaa-1.3.13.jar: ~/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/asciidoctor-diagram-1.5.9/lib/ditaamini-0.11.jar: ~/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/asciidoctor-diagram-1.5.9/lib/plantuml-1.3.13.jar: ~/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/asciidoctor-diagram-1.5.9/lib/plantuml.jar: ~/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/asciidoctor-diagram-1.5.9/lib/jlatexmath-minimal-1.0.5.jar: ~/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/asciidoctor-diagram-1.5.9/lib/batik-all-1.7.jar Launcher Type: SUN_STANDARD
به منظور محدود و فیلتر کردن خروجی، پارامترهای زیر وجود دارد:
پارامتر | کارکرد |
flags- | صرفا اطلاعات مرتبط با flag را نمایش میدهد. |
sysprops- | صرفا propertyهای سیستم را نمایش میدهد. |
jmap: چاپ دادههای مرتبط با کلاس
در قدم بعدی، لازم است دیدی نسبت به دادههای مرتبط با کلاسِ روی JVM به دست بیاورید. مانند آمارهای مربوط به بارگذاری کلاس، اشیای در انتظار finalizeشدن و heap اشیا.
میتوانید از دستور jmap برای جاپ جزییات یک فرآیند خاص استفاده کنید. بسته به پارامتر مورد استفاده، خروجی متفاوت خواهد بود.
جهت چاپ آمار کلاس بارگذاریشده:
jmap -clstats 95689
Index Super InstBytes KlassBytes annotations CpAll MethodCount Bytecodes MethodAll ROAll RWAll Total ClassName 1 -1 1686600 504 0 0 0 0 0 24 616 640 [B 2 -1 485288 504 0 0 0 0 0 24 616 640 [I 3 20 420984 616 128 14224 109 4577 64472 18640 62104 80744 java.lang.String 4 -1 375216 504 0 0 0 0 0 24 616 640 [C 5 20 374448 672 0 22120 139 5682 46936 24616 47008 71624 java.lang.Class 6 -1 238888 504 0 0 0 0 0 24 616 640 [Ljava.lang.Object; 7 20 165440 584 0 1392 7 149 1864 1152 3008 4160 java.util.HashMap$Node 8 20 141856 592 0 1368 9 213 2776 1488 3584 5072 java.util.concurrent.ConcurrentHashMap$Node 9 20 71120 584 0 1400 7 171 2264 1208 3384 4592 java.util.TreeMap$Entry ... 3085 3084 0 632 0 808 5 71 960 640 1920 2560 sun.util.resources.TimeZoneNamesBundle 3086 20 0 600 0 1256 5 159 1000 856 2264 3120 sun.util.resources.provider.NonBaseLocaleDataMetaInfo 5147912 1947360 10656 6473512 31831 1647775 9869272 6170712 13100408 19271120 Total 26.7% 10.1% 0.1% 33.6% - 8.6% 51.2% 32.0% 68.0% 100.0% Index Super InstBytes KlassBytes annotations CpAll MethodCount Bytecodes MethodAll ROAll RWAll Total ClassName
- جهت چاپ هیستوگرام heap اشیای جاوایی:
jmap -histo 95689
num #instances #bytes class name (module) ------------------------------------------------------- 1: 2578716 182530328 [I (java.base@11.0.1) 2: 261988 71251184 [Z (java.base@11.0.1) 3: 798811 57514392 java.util.regex.Matcher (java.base@11.0.1) 4: 413769 28433240 [B (java.base@11.0.1) 5: 296086 26055568 java.util.regex.Pattern (java.base@11.0.1) 6: 301073 16858024 [Ljava.lang.Object; (java.base@11.0.1) 7: 276719 15496264 [Ljava.util.regex.Pattern$GroupHead; (java.base@11.0.1) 8: 798811 13032760 [Ljava.util.regex.IntHashSet; (java.base@11.0.1) 9: 318781 7650744 java.util.regex.Pattern$BmpCharProperty (java.base@11.0.1) 10: 289648 6951552 java.util.ArrayList (java.base@11.0.1) ... 1616: 1 16 sun.util.logging.PlatformLogger (java.base@11.0.1) 1617: 1 16 sun.util.resources.LocaleData$LocaleDataStrategy (java.base@11.0.1) 1618: 1 16 sun.util.resources.cldr.provider.CLDRLocaleDataMetaInfo (jdk.localedata@11.0.1) Total 10605127 526098920
این دستور برای تشخیص نشت حافظه نیز استفاده میشود که قبلا در مقالهای مجزا، به تفصیل توضیح داده شده است.
jstack: چاپ نخهای موجود بر روی JVM
اگر مشکل مربوط به نخها (threads) باشد (مانند مشکل deadlock یا livelock)، جزییات مربوط به نخهای در حال اجرا، در دسترس هستند.
میتوانید از دستور jstack استفاده کرده و stack trace مربوط به یک فرآیند جاوایی خاص را ببینید.
jstack 95689
2018-12-07 19:06:01 Full thread dump OpenJDK 64-Bit Server VM (11.0.1+13 mixed mode): Threads class SMR info: _java_thread_list=0x00007fd1212fb270, length=13, elements={ 0x00007fd120015800, 0x00007fd120051000, 0x00007fd120053800, 0x00007fd11e89c000, 0x00007fd120045800, 0x00007fd11f00f800, 0x00007fd12004a800, 0x00007fd11e8d9800, 0x00007fd120065000, 0x00007fd11f883000, 0x00007fd11f075800, 0x00007fd11ed4b000, 0x00007fd11f30e800 } "main" #1 prio=5 os_prio=31 cpu=314567.92ms elapsed=2035.03s tid=0x00007fd120015800 nid=0x2403 runnable [0x000070000bbac000] java.lang.Thread.State: RUNNABLE at java.net.SocketInputStream.socketRead0(java.base@11.0.1/Native Method) at java.net.SocketInputStream.socketRead(java.base@11.0.1/SocketInputStream.java:115) at java.net.SocketInputStream.read(java.base@11.0.1/SocketInputStream.java:168) at java.net.SocketInputStream.read(java.base@11.0.1/SocketInputStream.java:140) at java.io.BufferedInputStream.fill(java.base@11.0.1/BufferedInputStream.java:252) at java.io.BufferedInputStream.read(java.base@11.0.1/BufferedInputStream.java:271) - locked <0x00000007000d0558> (a java.io.BufferedInputStream) at org.asciidoctor.diagram.HTTPInputStream.readLine(HTTPInputStream.java:20) at org.asciidoctor.diagram.HTTPInputStream.readRequest(HTTPInputStream.java:56) at org.asciidoctor.diagram.CommandServer.processRequests(CommandServer.java:61) at org.asciidoctor.diagram.CommandServer.main(CommandServer.java:25) ... "process reaper" #109 daemon prio=10 os_prio=31 cpu=538.50ms elapsed=1683.17s tid=0x00007fd11f30e800 nid=0x6507 waiting on condition [0x000070000ba4e000] java.lang.Thread.State: TIMED_WAITING (parking) at jdk.internal.misc.Unsafe.park(java.base@11.0.1/Native Method) - parking to wait for <0x000000070016fe20> (a java.util.concurrent.SynchronousQueue$TransferStack) at java.util.concurrent.locks.LockSupport.parkNanos(java.base@11.0.1/LockSupport.java:234) at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(java.base@11.0.1/SynchronousQueue.java:462) at java.util.concurrent.SynchronousQueue$TransferStack.transfer(java.base@11.0.1/SynchronousQueue.java:361) at java.util.concurrent.SynchronousQueue.poll(java.base@11.0.1/SynchronousQueue.java:937) at java.util.concurrent.ThreadPoolExecutor.getTask(java.base@11.0.1/ThreadPoolExecutor.java:1053) at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@11.0.1/ThreadPoolExecutor.java:1114) at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@11.0.1/ThreadPoolExecutor.java:628) at java.lang.Thread.run(java.base@11.0.1/Thread.java:834) "VM Thread" os_prio=31 cpu=1139.30ms elapsed=2035.01s tid=0x00007fd11f88e000 nid=0x4b03 runnable "GC Thread#0" os_prio=31 cpu=1888.39ms elapsed=2035.03s tid=0x00007fd11e805000 nid=0x5203 runnable "GC Thread#1" os_prio=31 cpu=1951.89ms elapsed=2034.53s tid=0x00007fd11e8e1800 nid=0x9903 runnable "GC Thread#2" os_prio=31 cpu=1897.20ms elapsed=2034.53s tid=0x00007fd11e8e2800 nid=0x5f03 runnable "GC Thread#3" os_prio=31 cpu=1901.78ms elapsed=2034.53s tid=0x00007fd11e90d000 nid=0x6103 runnable "G1 Main Marker" os_prio=31 cpu=0.57ms elapsed=2035.03s tid=0x00007fd11e84a000 nid=0x5003 runnable "G1 Conc#0" os_prio=31 cpu=36.31ms elapsed=2035.03s tid=0x00007fd11e84a800 nid=0x3003 runnable "G1 Refine#0" os_prio=31 cpu=8.48ms elapsed=2035.03s tid=0x00007fd11f882000 nid=0x3203 runnable "G1 Refine#1" os_prio=31 cpu=2.95ms elapsed=2034.52s tid=0x00007fd11e9b1000 nid=0x9703 runnable "G1 Refine#2" os_prio=31 cpu=0.06ms elapsed=2034.36s tid=0x00007fd11f939800 nid=0x6303 runnable "G1 Young RemSet Sampling" os_prio=31 cpu=898.32ms elapsed=2035.03s tid=0x00007fd11e858800 nid=0x3303 runnable "VM Periodic Task Thread" os_prio=31 cpu=933.68ms elapsed=2034.94s tid=0x00007fd11f00c800 nid=0xa603 waiting on condition JNI global refs: 98, weak refs: 5
برای چک کردن قفلها، از پارامتر l- استفاده کنید. به این ترتیب، خروجی زیر چاپ خواهد شد:
... "main" #1 prio=5 os_prio=31 cpu=489307.36ms elapsed=3019.58s tid=0x00007fd120015800 nid=0x2403 runnable [0x000070000bbac000] java.lang.Thread.State: RUNNABLE at java.net.SocketInputStream.socketRead0(java.base@11.0.1/Native Method) at java.net.SocketInputStream.socketRead(java.base@11.0.1/SocketInputStream.java:115) at java.net.SocketInputStream.read(java.base@11.0.1/SocketInputStream.java:168) at java.net.SocketInputStream.read(java.base@11.0.1/SocketInputStream.java:140) at java.io.BufferedInputStream.fill(java.base@11.0.1/BufferedInputStream.java:252) at java.io.BufferedInputStream.read(java.base@11.0.1/BufferedInputStream.java:271) - locked <0x00000007000d0558> (a java.io.BufferedInputStream) at org.asciidoctor.diagram.HTTPInputStream.readLine(HTTPInputStream.java:20) at org.asciidoctor.diagram.HTTPInputStream.readRequest(HTTPInputStream.java:56) at org.asciidoctor.diagram.CommandServer.processRequests(CommandServer.java:61) at org.asciidoctor.diagram.CommandServer.main(CommandServer.java:25) Locked ownable synchronizers: //1 - None "Reference Handler" #2 daemon prio=10 os_prio=31 cpu=0.94ms elapsed=3019.55s tid=0x00007fd120051000 nid=0x3603 waiting on condition [0x000070000c2c1000] java.lang.Thread.State: RUNNABLE at java.lang.ref.Reference.waitForReferencePendingList(java.base@11.0.1/Native Method) at java.lang.ref.Reference.processPendingReferences(java.base@11.0.1/Reference.java:241) at java.lang.ref.Reference$ReferenceHandler.run(java.base@11.0.1/Reference.java:213) Locked ownable synchronizers: //1 - None ...
1: همانطور که میبینید، هیچ قفلی وجود ندارد!
jconsole: نظارت بر یک JVM
داشتن یک دید بصری از داخل JVM در حال اجرا، میتواند بسیار مفید باشد.
با استفاده از دستور jconsole یک کنسول گرافیکی باز میشود که برای نظارت و مدیریت اپلیکیشنهای جاوایی میتوانید از آن بهره ببرید.
jconsole یکی از مهمترین ابزارهای توسعهدهندگان جاوا است.
این ابزار، در زمینههای مختلفی مانند آنچه در ادامه ذکر شده، دیدی بصری از یک JVM در حال اجرا به شما میدهد.
حافظه:
در این کنسول، میتوان نمودارهای مختلف مرتبط با حافظه مانند heap یا non-heap یا old gen یا eden یا survivor یا … را دید.
نخها:
در JConsole میتوان روند تعداد نخها در یک بازه زمانی دلخواه را مشاهده کرد. همچنین میتوان هر نخ را به صورت جداگانه به همراه نام، وضعیت و پشتهاش (stack) مشاهده کرد.
کلاسها:
تعداد کلاسهای بارگذاریشده را هم میتوان دید.
خلاصه VM:
این ابزار میتواند دادههای مرتبط با JVM را به ما نشان دهد. مانند
- آرگومانهای VM
- Class path
- Library path
- Boot class path
- سایز Heap
- غیره
- MBeans:
JConsole قادر است تمام Mbeanهای در دسترس را در یک ساختار درختی شامل ویژگیها و متدهایشان نمایش دهد. علاوه بر این، امکان مقداردهی به ویزگیها و یا فراخوانی متدها را هم به ما میدهد.
جمعبندی
JDK تعداد زیادی ابزار برای کمک به توسعهدهندگان دارد. چه از یک IDE استفاده کنید چه نکنید، این ابزارها کمکی بزرگ در کارهای روزانهتان هستند.
.
.
.
آدرس کانال تلگرام: JavaCupIR@
آدرس اکانت توییتر: JavaCupIR@
آدرس صفحه اینستاگرام: javacup.ir
آدرس گروه لینکدین: Iranian Java Developers
JDK Mission Control نیز برای بررسی پروسه جاوایی مناسب است.
شکرا
سوالی درمورد enum ذهنم را مشغول کرده اگر اساتید مشکل گشایی کنند ممنون می گردم .
در جاوا کلاس های بسیاری وجود دارد مثل دیتا استراکچر ها ، استریم ها ، کلاس های ریاضی گرافیکی و غیره و در مورد همه آنها با ایجاد یک شی می توانیم از آن کلاس و متد ها و قابلیت های آن استفاده نماییم در نتیجه ما با شی ای از آن کلاس ها سروکار داریم .
در مورد enum ولی ما خود یک کلاس می سازیم (با اینکه کلاس enum در جاوا وجود دارد ) و نه شی ای از آن کلاس enum .
خوب enumی که ما می سازیم یک کلاس است پس پیش فرض اینگونه درنظر می گیریم که کلاس enum که ما می سازیم می بایست کلاس enum جاوا را extend کند ولی می دانیم که ساختن enum به هیچ وجه بدینگونه نیست و فقط با نوشتن enum و دادن نام دلخواه کلاس ساخته می شود .
آیا کلاس enum ما بصورت ضمنی کلاس enum جاوا را ارثبری می کند ؟
اگر جواب سوال قبل بلی باشد از کدام متد آن استفاده می کند که بدین گونه عجیب اشیا را درون خود تعریف می کند در جاواداک چنین متدی مشاهده نکردم .
در جاواداک کلاس enum کانستراکتور دارد چرا نمی توانیم از کانستراکتور آن استفاده نماییم (مثلا به شکل new )؟
ودر نهایت اینکه چرا کلاس enum متد finalize را بسته است ؟
پیشاپیش سپاسگزارم
سلام تا اونحایی که بنده اطلاع داره کلاسی به نام Enum داریم که یک کلاس جنریک هست
در واقع شما وفتی یک enum برای مثال BOOK میسازی داری یک کلاس میسازی که از Enum ارث بری میکنه و متدی مثل name هم از اون کلاس اومده