두번째 시간으로, HotSpot JVM에서 제공하는 플래그의 다른 카테고리들을 소개한다. 또한, 나는 JIT 컴파일러 진단(diagnostics)와 연관된 몇가지 흥미로운 플래그들에 대해서 이야기할 것이다. JVM 플래그 카테고리들 HotSpot JVM은 세개의 플래그 카테고리들을 제공한다. 첫번째 카테고리는 표준 플래그(stand flag)들을 포함한다. 이름에서도 알수 있듯이, 기능적인부분과 표준 플래그들의 출력 모두 안정적이며 미래에 릴리즈 되는 JVM에서 잘 바뀌지 않을 것이다. java 실행시에 아무런 파라메터를 주지않으면 모든 표준 플래그 리스트들을 얻을 수 있다.(혹은 표준 출력이 있는 -help 파라메터를 사용하거나) 우리는 첫번째 시간에 몇몇 표준 플래그들을 이미 봤었다. 예를들어 […]
유용한 JVM 플래그 – Part 1 (JVM 타입들과 컴파일러 모드들)
현대의 JVM들은 효율적이고 안정적인 방법으로 자바 애플리케이션을(혹은 JVM과 호환되는 프로그래밍 언어들) 실행시키는 놀라운 일을 한다. 맞춤 메모리 관리(Adaptive memory management), 가비지 컬렉션(garbage collection), just-in-time compilation, 동적 클래스로딩(dynamic classloading), 락 최적화(lock optimization) – 이러한 것이 마법처럼 인용되지만 일반적인 프로그래머들에게 직접적으로 영향을 주진 않는다. 실행 시점에서, JVM은 지속적인 측정과 프로파일링을 기반으로 애플리케이션이나 그것의 일부를 핸들링하는 방법을 최적화한다. 여전히 JVM이 자동화 수준과 같은 것이나 그보다 못한 것들에 대해서 외부 모니터링이나 수동 튜닝을 위한 충분한 설비를 제공하고 있다는 것은 중요하다. 에러나 낮은 퍼포먼스의 경우에는 […]
[발 번역] 자바 가비지 컬렉션
이글은 Garbage Collectors Available In JDK 1.7.0_04 를 발 번역한 것입니다. Jack Shirazi 씨는 가비지 컬랙터가 무엇이고 오파클 자바 7 업데이트 4 JVM 에서 활용할 수 있는 가비지 컬렉터 조합에 대해서 말해줄 것입니다. Published June 2012, Author Jack Shirazi 마침내 G1 을 공식적으로 – i.e. 더 이상 실험적 가비지 컬렉터가 아니다 – 1.7.0_04 (Java 7 update 4) 릴리즈에서 지원되며 이것은 이제 Sun JVM 의 가비지 컬렉터 측면에서 활용가능한 가치있는 주식(?)을 가지는 중임을 말한다. 아래에 기술할 자세한 사항은 다른 많은 Sun JVM […]
JAVA에서 스크린 Refresh 하기
리눅스 터미널에서 실행되는 각종 모니터링 프로그램들을 보면 화면이 그대로 인채 수치만 바뀌는 형식을 취하는 프로그램들이 많다. 사실 터미널 스크린을 빠르게 Refresh 하는것인데, 자바에서는 다음과 같이 프로그래밍을 하면 된다.
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 |
import java.io.Console; public class monitor_jmx { public static final char ESC = 27; public static void main(String[] args) throws Exception{ // TODO Auto-generated method stub Console c = System.console(); if (c == null) { System.err.println("no console"); System.exit(1); } // clear screen only the first time c.writer().print(ESC + "[2J"); c.flush(); Thread.sleep(200); for (int i = 0; i < 100; ++i) { // reposition the cursor to 1|1 c.writer().print(ESC + "[1;1H"); c.flush(); c.writer().println("hello " + i); c.flush(); Thread.sleep(200); } } } |
Console 객체를 이용해 구현한다.
Jmxterm – 커맨드 라인 JMX
JAVA 에는 JMX(Java Management Extension) 이라고해서 JAVA 애플리케이션을 관리하기 위한 확장을 제공합니다. JAVA 애플리케이션을 시작할때에 다음과 같이 JVM 옵션을 주게되면 사용할 수 있습니다. -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port -Dcom.sun.management.jmxremote.authenticate -Djava.rmi.server.hostname -Dcom.sun.management.jmxremote.ssl hostname, port 그리고 authenticate 을 설정하면 특정 호스트에서 특정포트를 통해서 인증을 통해서 JMX 클라이언트를 통해서 접속할 수 있는데, JMX 클라이언트로 가장 유명한 것이 JConsole 입니다. 그런데, 보안상의 이유로 JMX 는 활성화하되 접속은 로컬호스트에서만 되도록 설정을 해놓는 경우가 많습니다. 다음과 같이 말입니다.
1 2 3 4 5 |
export JMX_OPTS=" -Dcom.sun.management.jmxremote \ -Dcom.sun.management.jmxremote.port=8090 \ -Dcom.sun.management.jmxremote.authenticate=false \ -Djava.rmi.server.hostname=localhost \ -Dcom.sun.management.jmxremote.ssl=false " |
대부분의 로컬호스트가 리눅스일 경우에는 JConsole 을 이용하기 위해서는 터미널의 터널링을 […]
Java 디폴트 옵션 알아내기.
Java 로 프로그램을 실행할때에는 많은 옵션들을 줄 수가 있다. 대표적으로 최소, 최대 힙(Heap) 크기와 가비지 컬렉터(Garbage Collector)를 무엇으로 할 것인지 하는 것이다. 그런데, 이러한 옵션들이 없다면 Java 는 기본적으로 어떤 값으로 동작을 하게될까? 이 물음에 대한 답은 다음의 명령어로 알아 볼 수 있다.
1 |
./java -XX:+PrintCommandLineFlags -version |
위와 같이 실행을 하면 기본적인 값들을 보여준다. 다음은 Linux X86_64 에서 Java 버전별로 가지는 기본값들 이다. jdk1.6.0_45
1 2 3 4 5 |
./java -XX:+PrintCommandLineFlags -version -XX:InitialHeapSize=95137024 -XX:MaxHeapSize=1522192384 -XX:ParallelGCThreads=4 -XX:+PrintCommandLineFlags -XX:+UseCompressedOops -XX:+UseParallelGC java version "1.6.0_45" Java(TM) SE Runtime Environment (build 1.6.0_45-b06) Java HotSpot(TM) 64-Bit Server VM (build 20.45-b01, mixed mode) |
jdk1.7.0_75
1 2 3 4 5 |
./java -XX:+PrintCommandLineFlags -version -XX:InitialHeapSize=95137024 -XX:MaxHeapSize=1522192384 -XX:+PrintCommandLineFlags -XX:+UseCompressedOops -XX:+UseParallelGC java version "1.7.0_75" Java(TM) SE Runtime Environment (build 1.7.0_75-b13) Java HotSpot(TM) 64-Bit Server VM (build 24.75-b04, mixed mode) |
jdk1.8.0_40
1 2 3 4 5 |
./java -XX:+PrintCommandLineFlags -version -XX:InitialHeapSize=95137024 -XX:MaxHeapSize=1522192384 -XX:+PrintCommandLineFlags -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseParallelGC java version "1.8.0_40" Java(TM) SE Runtime Environment (build 1.8.0_40-b26) Java HotSpot(TM) 64-Bit Server VM (build 25.40-b25, mixed mode) |
JMX 로 Tomcat 모니터링 하기.
톰캣(Tomcat)은 JEE의 Web Container 의 구현에 입니다. 흔히 WAS 서버라고 하죠. 많은 기능이 있지만 이번에는 JMX를 설정하고 이를 이용해서 Tomcat 을 모니터링 해보겠습니다. JMX는 Java Management eXtension 으로 자바 서비스들을 관리하고 모니터링하기위한 API를 제공하는 기능을 포함하는 기술입니다. Tomcat 오 자바 서비스의 일종임으로 JMX를 이용할 수 있습니다. 톰캣(Tomcat)의 경우에 아쉽게도 기본 배포본에 이를 위한 라이브러리가 포함되어 있지않아 이 기능을 이용하기 위해서는 톰캣용 JMX 라이브러리를 다운받고 톰캣을 재시작 해줘야 합니다.
1 2 |
# 톰캣버전에 맞는 JMX 를 다운받으시길 바랍니다. http://apache.mirror.cdnetworks.com/tomcat/tomcat-7/v7.0.57/bin/extras/catalina-jmx-remote.jar |
이 파일을 톰캣(Tomcat) 라이브러리 디렉토리인 lib 에 넣어줍니다. 그리고 톰캣(Tomcat)시작 스크립트에 […]
jstack 과 thread Id, CPU, Mem 사용량 체크.
jstack 은 자바 애플리케이션의 쓰레드(Thread) 덤프를 뜰 수 있도록 도와주는 도구 입니다. 자바 애플리케이션의 쓰레드의 상태를 상세히 알 수 있어서 자바 애플리케이션의 프로파일링을 할 수 있고 이를 통해서 성능을 개선할 수 있습니다. 예를들면 다음과 같습니다.
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 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
2015-01-21 21:11:12 Full thread dump OpenJDK 64-Bit Server VM (23.25-b01 mixed mode): "Attach Listener" daemon prio=10 tid=0x00007fa830001000 nid=0x3c5a waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE Locked ownable synchronizers: - None "ajp-bio-8309-AsyncTimeout" daemon prio=10 tid=0x00007fa85ca18000 nid=0x2e47 waiting on condition [0x00007fa8508f4000] java.lang.Thread.State: TIMED_WAITING (sleeping) at java.lang.Thread.sleep(Native Method) at org.apache.tomcat.util.net.JIoEndpoint$AsyncTimeout.run(JIoEndpoint.java:152) at java.lang.Thread.run(Thread.java:701) Locked ownable synchronizers: - None "ajp-bio-8309-Acceptor-0" daemon prio=10 tid=0x00007fa85ca16000 nid=0x2e46 runnable [0x00007fa8509f5000] java.lang.Thread.State: RUNNABLE at java.net.PlainSocketImpl.socketAccept(Native Method) at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:375) at java.net.ServerSocket.implAccept(ServerSocket.java:478) at java.net.ServerSocket.accept(ServerSocket.java:446) at org.apache.tomcat.util.net.DefaultServerSocketFactory.acceptSocket(DefaultServerSocketFactory.java:60) at org.apache.tomcat.util.net.JIoEndpoint$Acceptor.run(JIoEndpoint.java:220) at java.lang.Thread.run(Thread.java:701) Locked ownable synchronizers: - None "http-bio-8380-AsyncTimeout" daemon prio=10 tid=0x00007fa85ca13800 nid=0x2e45 waiting on condition [0x00007fa850af6000] java.lang.Thread.State: TIMED_WAITING (sleeping) at java.lang.Thread.sleep(Native Method) at org.apache.tomcat.util.net.JIoEndpoint$AsyncTimeout.run(JIoEndpoint.java:152) at java.lang.Thread.run(Thread.java:701) Locked ownable synchronizers: - None "http-bio-8380-Acceptor-0" daemon prio=10 tid=0x00007fa85ca12000 nid=0x2e44 runnable [0x00007fa850bf7000] java.lang.Thread.State: RUNNABLE at java.net.PlainSocketImpl.socketAccept(Native Method) at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:375) at java.net.ServerSocket.implAccept(ServerSocket.java:478) at java.net.ServerSocket.accept(ServerSocket.java:446) at org.apache.tomcat.util.net.DefaultServerSocketFactory.acceptSocket(DefaultServerSocketFactory.java:60) at org.apache.tomcat.util.net.JIoEndpoint$Acceptor.run(JIoEndpoint.java:220) at java.lang.Thread.run(Thread.java:701) Locked ownable synchronizers: - None "ContainerBackgroundProcessor[StandardEngine[Catalina]]" daemon prio=10 tid=0x00007fa85ca0f800 nid=0x2e43 waiting on condition [0x00007fa850cf8000] java.lang.Thread.State: TIMED_WAITING (sleeping) at java.lang.Thread.sleep(Native Method) at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1513) at java.lang.Thread.run(Thread.java:701) Locked ownable synchronizers: - None "GroupChannel-Heartbeat-1" daemon prio=10 tid=0x00007fa85ca0b800 nid=0x2e40 waiting on condition [0x00007fa85100d000] java.lang.Thread.State: TIMED_WAITING (sleeping) at java.lang.Thread.sleep(Native Method) at org.apache.catalina.tribes.group.GroupChannel$HeartbeatThread.run(GroupChannel.java:689) Locked ownable synchronizers: - None "Tribes-MembershipSender" daemon prio=10 tid=0x00007fa85ca0a000 nid=0x2e3e waiting on condition [0x00007fa85110e000] java.lang.Thread.State: TIMED_WAITING (sleeping) at java.lang.Thread.sleep(Native Method) at org.apache.catalina.tribes.membership.McastServiceImpl$SenderThread.run(McastServiceImpl.java:580) Locked ownable synchronizers: - None "Tribes-MembershipReceiver" daemon prio=10 tid=0x00007fa85ca08800 nid=0x2e3d runnable [0x00007fa85120f000] java.lang.Thread.State: RUNNABLE at java.net.PlainDatagramSocketImpl.receive0(Native Method) - locked <0x00000000a5730da0> (a java.net.PlainDatagramSocketImpl) at java.net.AbstractPlainDatagramSocketImpl.receive(AbstractPlainDatagramSocketImpl.java:136) - locked <0x00000000a5730da0> (a java.net.PlainDatagramSocketImpl) at java.net.DatagramSocket.receive(DatagramSocket.java:759) - locked <0x00000000a5803e80> (a java.net.DatagramPacket) - locked <0x00000000a5803e48> (a java.net.MulticastSocket) at org.apache.catalina.tribes.membership.McastServiceImpl.receive(McastServiceImpl.java:339) at org.apache.catalina.tribes.membership.McastServiceImpl$ReceiverThread.run(McastServiceImpl.java:533) Locked ownable synchronizers: - None "NioReceiver" daemon prio=10 tid=0x00007fa85c9da800 nid=0x2e3c runnable [0x00007fa851310000] java.lang.Thread.State: RUNNABLE at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method) at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:228) at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:83) at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:87) - locked <0x00000000a57ca768> (a sun.nio.ch.Util$1) - locked <0x00000000a57ca758> (a java.util.Collections$UnmodifiableSet) - locked <0x00000000a57ca710> (a sun.nio.ch.EPollSelectorImpl) at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:98) at org.apache.catalina.tribes.transport.nio.NioReceiver.listen(NioReceiver.java:283) at org.apache.catalina.tribes.transport.nio.NioReceiver.run(NioReceiver.java:433) at java.lang.Thread.run(Thread.java:701) Locked ownable synchronizers: - None "GC Daemon" daemon prio=10 tid=0x00007fa85c934000 nid=0x2e38 in Object.wait() [0x00007fa85183a000] java.lang.Thread.State: TIMED_WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x00000000a55cc360> (a sun.misc.GC$LatencyLock) at sun.misc.GC$Daemon.run(GC.java:117) - locked <0x00000000a55cc360> (a sun.misc.GC$LatencyLock) Locked ownable synchronizers: - None "Low Memory Detector" daemon prio=10 tid=0x00007fa85c0fa000 nid=0x2e36 runnable [0x0000000000000000] java.lang.Thread.State: RUNNABLE Locked ownable synchronizers: - None "C2 CompilerThread1" daemon prio=10 tid=0x00007fa85c0f8000 nid=0x2e35 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE Locked ownable synchronizers: - None "C2 CompilerThread0" daemon prio=10 tid=0x00007fa85c0f5000 nid=0x2e34 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE Locked ownable synchronizers: - None "Signal Dispatcher" daemon prio=10 tid=0x00007fa85c0f2800 nid=0x2e33 runnable [0x0000000000000000] java.lang.Thread.State: RUNNABLE Locked ownable synchronizers: - None "Finalizer" daemon prio=10 tid=0x00007fa85c0a4000 nid=0x2e32 in Object.wait() [0x00007fa85254c000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x00000000a57188a8> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:133) - locked <0x00000000a57188a8> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:149) at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:189) Locked ownable synchronizers: - None "Reference Handler" daemon prio=10 tid=0x00007fa85c0a2000 nid=0x2e31 in Object.wait() [0x00007fa85264d000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x00000000a57ff5a0> (a java.lang.ref.Reference$Lock) at java.lang.Object.wait(Object.java:502) at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133) - locked <0x00000000a57ff5a0> (a java.lang.ref.Reference$Lock) Locked ownable synchronizers: - None "main" prio=10 tid=0x00007fa85c009000 nid=0x2e2b runnable [0x00007fa86611b000] java.lang.Thread.State: RUNNABLE at java.net.PlainSocketImpl.socketAccept(Native Method) at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:375) at java.net.ServerSocket.implAccept(ServerSocket.java:478) at java.net.ServerSocket.accept(ServerSocket.java:446) at org.apache.catalina.core.StandardServer.await(StandardServer.java:453) at org.apache.catalina.startup.Catalina.await(Catalina.java:777) at org.apache.catalina.startup.Catalina.start(Catalina.java:723) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:622) at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:321) at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:455) Locked ownable synchronizers: - None "VM Thread" prio=10 tid=0x00007fa85c093000 nid=0x2e30 runnable "GC task thread#0 (ParallelGC)" prio=10 tid=0x00007fa85c016800 nid=0x2e2c runnable "GC task thread#1 (ParallelGC)" prio=10 tid=0x00007fa85c018800 nid=0x2e2d runnable "GC task thread#2 (ParallelGC)" prio=10 tid=0x00007fa85c01a000 nid=0x2e2e runnable "GC task thread#3 (ParallelGC)" prio=10 tid=0x00007fa85c01c000 nid=0x2e2f runnable "VM Periodic Task Thread" prio=10 tid=0x00007fa85c105000 nid=0x2e37 waiting on condition JNI global references: 127 |
문제는 이렇게 jstack 의 결과을 보면 당시 쓰레드에 OS 의 자원사용량을 알 방법이 없습니다. OS의 자원이라고 하면 CPU, MEM 등과 같은 것입니다. jstack 의 결과에는 tid 라고 해서 Thread ID 가 헥사(16 진수)로 표시됩니다. 이는 OS상에서 자바 애플리케이션의 쓰레드의 PID 를 가리킵니다. 그래서 jstack […]