BTrace

Development/Java 2012. 2. 2. 04:33

BTrace - 1. 소개

BTrace - 1. 소개

BTrace 는 ByteCode Dynamic Trace 의 약자로 DTrace 에 착안을 해서 만들어진 동적 Java process 추적 툴입니다. DTrace 의 개념에 착안해서 만들어진 Java 용 DTrace 라고 생각하시면 이해가 제일 빠르실 겁니다. DTrace 가 생소하신 분들은 sdnkorea blog 의 DTrace Startup Guide 를 먼저 살펴보시기 바랍니다. BTrace 는 현재 jdk6 이상에서만 사용이 가능하며 아직까지는 draft 버전으로 종종 JVM crash 를 유발하기도 합니다. BTrace 는 특정메소드의 호출 혹은 특정 클래스에 관련된 이벤트들을 특수한 코딩이 필요 없이 동적으로 추적할 수 있으므로 현재 실행중인 java process 의 중단 없이 내부를 추적할 수 있는 매우 유용한 툴 입니다. 

사용법은 DTrace 와 매우 유사 합니다. DTrace 는 D 언어 스크립트를 현재 실행중인 process 를 target 으로 실행 하듯이 BTrace 는 BTrace 소스(java) 를 실행중인 java process 를 target 으로 실행 합니다. 
예)
  btrace 4448 AllCall.java (여기서 4448 은 java pid)

프로그램을 추적하려면 어떠한 지점(혹은 이벤트)를 추적할지에 대한 point 설정과 해당 point 에서 필요한 정보를 얻어낼 수 있는 action 코드가 필요할 것입니다. BTrace 스크립트는 사용자가 지정한 probe point (특정 지점 혹은 이벤트로) 에 도달하면 (보통 probe 가 fire 됐다고 표현 합니다) Action 메소드 에서 정의한 코드를 수행합니다. probe point 는 @OnMethod 어노테이션을 이용해서 지정합니다.
지정하는 방법은 Aspectj 의 point-cut 설정과 유사하여 클래스별, 메소드별로 설정할 수 있도록 되어 있습니다.

BTrace 는 현재 실행중인 process 를 추적하기 위한 툴이므로 실행중인 process 에 어떠한 영향도 주어서는 안됩니다. 즉 읽기전용으로 동작해야 된다는 뜻입니다. 그러므로 BTrace 스크립트에서는 오브젝트 생성이나 exception 생성 및 throw, 다른 메소드의 호출등이 불가능 합니다. 이러한 제약조건은 글의 마지막에 정리해 보도록 하겠습니다.

기본적인 개념 설명은 여기서 끝내고 직접 BTrace 스크립트를 보고 설명을 드리도록 하겠습니다.

예제) (BTrace sample 디렉토리의 AllCall1.java)
package com.sun.btrace.samples;

import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;

/**
 * This script demonstrates the possibility to intercept
 * method calls that are abou to be executed from the body of
 * a certain method. This is achieved by using the {@linkplain Kind#CALL}
 * location value.
 */
    @OnMethod(clazz="javax.swing.JTextField", method="/.*/",
              location=@Location(value=Kind.CALL, clazz="/.*/", method="/.*/"))
    public static void m(Object self, String method) { // all calls to the methods with signature "()"
    println(method);
    println(probeMethod());
    println(probeClass());
    }

위의 스크립트는 javax.swing.JTextField 클래스를 호출하는(Kind.Call) 모든 Class(clazz="/.*/") 의 모든 method (method="/.*/") 들을 추적하여 TextField 메소드들 중에서 매개변수가 없는(즉 signature 가 () 인) 메소드를 호출한 호출자의 메소드 이름을 출력해 주는 예제입니다. 해당 스크립트를 Java2D(jdk demo\jfc 에 존재하는) 를 target 으로 실행하면 다음과 같은 결과를 보실 수 있습니다.

getInsets()Ljava/awt/Insets;
scrollRectToVisible
class javax.swing.JTextField

즉 JTextField의 scrollRectToVisible 메소드가 java.asw.Insets 의 getInsets 메소드에서 호출 되고 있음을 나타냅니다.

위의 OnMethod 에서 눈여겨 볼 부분은 @Location annotation 입니다. Location 의 종류는 여러가지가 있는데 몇가지만 소개 하면 다음과 같습니다.

  Kind.Call   : 해당 Class 의 해당 method 를 호출한 시점
  Kind.Catch  : method 의 exception 이 catch 되는 시점
  Kind.Entry  : method 가 호출 되기 바로 직전
  Kind.Return : method 가 return 된 직후에
  Kind.Line   : method 의 해당 라인이 실행될때
  Kind.Throw  : method 가 exception 을 throw 할 때
  
각각의 Location 에 따라서 Action Method 에 Argument 들이 달라집니다. 예를 들어 Kind.Call 의 경우는

  Object self, String method, Object arg1, Object arg2....

이런식으로 해당 probe point 를 호출하는 클래스 자체(self) 와 호출하는 메소드 이름(method), 그리고 메소드의 signature 즉 입력 매개변수들인 arg1, arg2 등을 매개변수로 받게 됩니다.(위의 m 메소드 참조)

Kind.Entry 및 Return 의 경우는
  Object returned
  
즉 probe point 가 호출되고 나서 리턴되는 object(returned) 를 매개변수로 받게 됩니다. 즉 아래의 예를  보시기 바랍니다.

   @OnMethod(
     clazz="java.lang.ClassLoader", 
     method="defineClass",
     location=@Location(Kind.RETURN)
   )   
   public static void defineclass(Class cl) {
       println(strcat("loaded ", name(cl)));
       jstack();
       println("==========================");
   }
   
java.lang.ClassLoader.defineClass 의 return object 인 Class 타입을 매개변수로 받습니다.

BTrace 에 대한 간단한 소개는 이것으로 마치고 다음 글에는 action 메소드에서 유일하게 호출 가능한 com.sun.btrace.BTraceUtils 의 메소드들에 대해 설명 드리도록 하겠습니다.

첨부) action method 의 제약사항
1. 새로운 object 생성 불가
2. 새로운 array 생성 불가
3. exception throw 불가
4. exception catch 불가
5. 임시 instance 및 static method 호출 불가 -오직 com.sun.btrace.BTraceUtils 클래스의 static method 만 호출 가능
6. 타겟 프로그램의 클래스 혹은 오브젝트에 값의 설정 불가함. 그러나 BTrace class 자체의 state field 들에 대한 설정은 가능함.
7. public static void 타입의 method 만 BTrace 클래스의 메소드로 허락됨
8. inner, outer local 클래스의 사용 불가
8. 동기화 사용 불가(synchronized)
9. loop 사용 불가. 단 if 구문은 사용 가능함.
10. extend 불가능
11. 인터페이스 implement 불가
12. asset 구문 삽입 불가
13. Class literal 즉 this 의 사용 불가

출처 -  http://eggboy.egloos.com/1866372 
=================================================================================================

2011년 6월 19일에 진행되는 JCO 교육에 참석하실 분들은 아래의 가이드대로 준비한 후 교육장에 참석하셔야만 합니다. (그렇지 않으신 경우 제대로 된 교육이 진행되지 않습니다.)

1. BTrace 다운로드
아래 URL에서 본인이 지참하시는 PC의 OS에 맞는 라이브러리를 다운로드 합니다.
http://kenai.com/projects/btrace/downloads/directory/releases/release-1.2 

2. JDK 설치
Mac 사용자는 상관 없지만,
윈도우 사용자분들은 JDK를 반드시 6.0 이상 설치하셔야 하며,
C:\jdk1.6 폴더에 설치해 주시길 권장합니다.
C:\Program files 아래에 JDK를 설치하시면 실습이 매우 어려우니,
귀찮으시더라도 해당 폴더에 설치해 주시길 권장합니다.

3. 샘플 소스 다운로드
아래의 샘플 소스를 참석하실 PC에 다운로드 하셔서 갖고 오셔야만 합니다.



이렇게 필요한 파일들만 받고 설치해 주시면 교육 준비는 끝납니다.
실제 필요한 설정은 교육 시간에 진행되오니 걱정 안하셔도 됩니다.

감사합니다









'Development > Java' 카테고리의 다른 글

Heap dump란?  (0) 2012.02.02
ClassLoader 문제 분석  (0) 2012.02.02
jstat 유틸을 이용하면 JVM상태를 상세하게 모니터링 할 수 있다.  (0) 2012.02.02
java.lang.OutOfMemoryError: PermGen space  (0) 2012.02.02
스윙(Swing)  (0) 2012.01.30
Posted by linuxism
,

jstat 유틸

  • jstat 유틸을 이용하면 JVM상태를 상세하게 모니터링 할 수 있다.

사용방법

  • jstat 사용법
jstat [일반옵션|출력옵션 vmid[간격[수행횟수]]]
jstat [ generalOption | outputOptions vmid [interval[s|ms] [count]] ]
  • 아래와 같이 사용하면 된다.
    • gcutil 옵션으로 5초 간격으로 JVM 상태 조회하는 예제이다.
    • 11459는 리눅스에서 JAVA 프로세스 아이디이다.
    • 윈도우에서도 동일하게 프로세스 아이디를 조회하여 사용하면 된다.
oracleclub@localhost~]$ jstat -gcutil 11459 5s


  S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT  
  0.00  63.38  14.21  29.96  99.94    115    9.854     0    0.000    9.854
  0.00  63.38  28.20  29.96  99.70    115    9.854     0    0.000    9.854
  0.00  63.38  29.39  29.96  99.70    115    9.854     0    0.000    9.854
  0.00  63.38  29.80  29.96  99.70    115    9.854     0    0.000    9.854
  0.00  63.38  32.29  29.96  99.70    115    9.854     0    0.000    9.854
  • gcutil 옵션의 값 설명
    • S0 : Survivor 0 영역
    • S1 : Survivor 1 영역
    • E : Eden 영역, Young Area (Miner GC)
    • O : Old 영역, (Mager GC)
    • P : Permanent Area
    • YGC : Young GC Count
    • YGCT : Young GC Time Total
    • FGC : Full GC Count
    • FGCT : Full GC Time Total
    • GCT : Young GC + Full GC

jstats 옵션 조회

  • 아래와 같이 -options 으로 조회 할 수 있다.
oracleclub@localhost~]$ jstat -options
  
-class : 클래스 로딩 통계정보
-compiler
-gc
-gccapacity
-gccause
-gcnew
-gcnewcapacity
-gcold
-gcoldcapacity
-gcpermcapacity
-gcutil
-printcompilation
  • 아래는 gccapacity 옵션의 예이다.
oracleclub@localhost~]$ jstat -gccapacity  11459 5s

 NGCMN    NGCMX     NGC     S0C   S1C       EC      OGCMN      OGCMX       OGC         OC      PGCMN    PGCMX     PGC       PC     YGC    FGC
349504.0 349504.0 349504.0 3712.0 3648.0 342144.0   699072.0   699072.0   699072.0   699072.0  16384.0 262144.0  40448.0  40448.0    116     0
349504.0 349504.0 349504.0 3712.0 3648.0 342144.0   699072.0   699072.0   699072.0   699072.0  16384.0 262144.0  40448.0  40448.0    116     0
349504.0 349504.0 349504.0 3712.0 3648.0 342144.0   699072.0   699072.0   699072.0   699072.0  16384.0 262144.0  40448.0  40448.0    116     0
349504.0 349504.0 349504.0 3712.0 3648.0 342144.0   699072.0   699072.0   699072.0   699072.0  16384.0 262144.0  40448.0  40448.0    116     0
349504.0 349504.0 349504.0 3712.0 3648.0 342144.0   699072.0   699072.0   699072.0   699072.0  16384.0 262144.0  40448.0  40448.0    116     0
349504.0 349504.0 349504.0 3712.0 3648.0 342144.0   699072.0   699072.0   699072.0   699072.0  16384.0 262144.0  40448.0  40448.0    116     0

문서정보







1. ps -ef | grep java로 pid알아내기

2. 아래와같이 확인

 jstat -gcutil -h20 -t 7251 3000 3000

      -> gcutil : gcutil 에 대해서 수행

      -> -h20 : 20라인마다 header 찍음

      -> -t : time stamp 프린트(JVM 이 스타트 된 이후의 시간)

      -> 7251 : 프로세스 id

      -> 3000 : interval (ms 단위)

      -> 3000 : count

[출처] jstat로 jvm모니터링하기|작성자 GoGo


출처 -  http://blog.naver.com/oshnew?Redirect=Log&logNo=10101015818 











. jstat 수행 방법
   - 우선 모니터링 하고자 하는 프로세스의 ID 를 확인합니다.
      확인하는 방법은 ps -ef | grep java 로 확인을 해도 되고, 프롬프트 상태에서 jps 라고 입력한 뒤 엔터를 치면 해당 JVM에서 수행된 프로세스의 ID를 보여줍니다.
      (jps 사용시에는 PATH에 해당 JDK가 설정되어 있어야 합니다.
 
 

  - 두번째로 jstat 명령을 수행 합니다.

      jstat -gcutil -h20 -t 7251 3000 3000

      -> gcutil : gcutil 에 대해서 수행

      -> -h20 : 20라인마다 header 찍음

      -> -t : time stamp 프린트(JVM 이 스타트 된 이후의 시간)

      -> 7251 : 프로세스 id

      -> 3000 : interval (ms 단위)

      -> 3000 : count
 
 - 수행 결과
 
2. 각각의 항목 설명

  - S0 Survivor 영역 0 의 사용율 (현재의 용량에 대한 퍼센티지)

  - S1 Survivor 영역 1 의 사용율 (현재의 용량에 대한 퍼센티지)

  - Eden 영역의 사용율 (현재의 용량에 대한 퍼센티지)

  - Old 영역의 사용율 (현재의 용량에 대한 퍼센티지)

  - Permanent 영역의 사용율 (현재의 용량에 대한 퍼센티지)

  - YGC Young 세대의 GC 이벤트수

  - YGCT Young 세대의 가베지 콜렉션 시간

  - FGC 풀 GC 이벤트수

  - FGCT 풀 가베지 콜렉션 시간

  - GCT : 가베지 콜렉션총시간
 
3. 샘플

  >jstat -gcutil 21891 250 7
      S0     S1     E      O      P     YGC    YGCT    FGC    FGCT     GCT
     12.44   0.00  27.20   9.49  96.70    78    0.176     5    0.495    0.672
     12.44   0.00  62.16   9.49  96.70    78    0.176     5    0.495    0.672
     12.44   0.00  83.97   9.49  96.70    78    0.176     5    0.495    0.672
      0.00   7.74   0.00   9.51  96.70    79    0.177     5    0.495    0.673
      0.00   7.74  23.37   9.51  96.70    79    0.177     5    0.495    0.673
      0.00   7.74  43.82   9.51  96.70    79    0.177     5    0.495    0.673
      0.00   7.74  58.11   9.51  96.71    79    0.177     5    0.495    0.673

 

    이 예의 출력은, Young 세대의 콜렉션이 3 번째와 4 번째의 샘플간에 행해진 것을 나타내고 있습니다.

    콜렉션에는 0.001 초 걸리고 있어 오브젝트가 Eden 영역 (E)으로부터 Old 영역 (O)에 승격했기 때문에,

    Old 영역의 사용율은 9.49% 에서 9.51% 에 증가하고 있습니다.

    Survivor 영역은, 콜렉션전은 12.44% 가 사용되고 있었습니다만, 콜렉션 후는 7.74% 밖에 사용되고 있지 않습니다.

 

실시간으로 메모리 사용을 좀 확인해야 하는 상황에서는 위와 같이 jstat 로 간단하게 모니터링을 수행하면

현재의 JVM 메모리 사용 상황을 확인이 가능할 것 같습니다.

 

가장 정확한 건 GC 로그를 별도의 파일로 출력하게 해서 분석하는 것이지만, 이럴 경우에는 실시간으로 확인이 힘들기 때문에

위와 같이 사용하는 것도 괜찮은 방법 중의 하나일 것 같습니다.

물론 JVM 에 계속 request 를 보내기 때문에 부하가 있을 듯 하지만, 지금 생각으로는 크게 영향은 미치지 않을 듯 하네요..

영향이 고려되면 interval을 좀 조정하든지 하면 될 듯 합니다.

출처 -  http://blog.naver.com/solvage?Redirect=Log&logNo=10038025715 





[root@CentOS ~]# jstat
invalid argument count
Usage: jstat -help|-options
       jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]

Definitions:
  <option>      An option reported by the -options option
  <vmid>        Virtual Machine Identifier. A vmid takes the following form:
                     <lvmid>[@<hostname>[:<port>]]
                Where <lvmid> is the local vm identifier for the target
                Java virtual machine, typically a process id; <hostname> is
                the name of the host running the target Java virtual machine;
                and <port> is the port number for the rmiregistry on the
                target host. See the jvmstat documentation for a more complete
                description of the Virtual Machine Identifier.
  <lines>       Number of samples between header lines.
  <interval>    Sampling interval. The following forms are allowed:
                    <n>["ms"|"s"]
                Where <n> is an integer and the suffix specifies the units as 
                milliseconds("ms") or seconds("s"). The default units are "ms".
  <count>       Number of samples to take before terminating.
  -J<flag>      Pass <flag> directly to the runtime system.

여기서  vmid는 Virtual Machine Identifier 이다.

그래서 Virtual Machine Identifier 부분을 0으로 설정

[root@CentOS5 ~]# jstat -gcutil 0 5s
  S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT   
  0.00  58.05  73.05   0.00   2.80      1    0.006     0    0.000    0.006
  0.00  58.05  73.05   0.00   2.88      1    0.006     0    0.000    0.006
  0.00  58.05  75.01   0.00   2.88      1    0.006     0    0.000    0.006
  0.00  58.05  75.01   0.00   2.88      1    0.006     0    0.000    0.006
  0.00  58.05  76.97   0.00   2.88      1    0.006     0    0.000    0.006
  0.00  58.05  76.97   0.00   2.88      1    0.006     0    0.000    0.006

 





Java Platform, Standard Edition Tools Reference
Contents    Previous    Next


jstat

Monitors Java Virtual Machine (JVM) statistics. This command is experimental and unsupported.

Synopsis

jstat [ generalOption | outputOptions vmid [ interval[s|ms] [ count ] ]

generalOption

A single general command-line option -help or -options. See General Options.

outputOptions

One or more output options that consist of a single statOption, plus any of the -t-h, and -J options. See Output Options.

vmid

Virtual machine identifier, which is a string that indicates the target JVM. The general syntax is the following:

[protocol:][//]lvmid[@hostname[:port]/servername]

The syntax of the vmid string corresponds to the syntax of a URI. The vmid string can vary from a simple integer that represents a local JVM to a more complex construction that specifies a communications protocol, port number, and other implementation-specific values. See Virtual Machine Identifier.

interval [s|ms]

Sampling interval in the specified units, seconds (s) or milliseconds (ms). Default units are milliseconds. Must be a positive integer. When specified, the jstat command produces its output at each interval.

count

Number of samples to display. The default value is infinity which causes the jstat command to display statistics until the target JVM terminates or the jstat command is terminated. This value must be a positive integer.

Virtual Machine Identifier

The syntax of the vmid string corresponds to the syntax of a URI:

[protocol:][//]lvmid[@hostname[:port]/servername]
protocol

The communications protocol. If the protocol value is omitted and a host name is not specified, then the default protocol is a platform-specific optimized local protocol. If the protocol value is omitted and a host name is specified, then the default protocol is rmi.

lvmid

The local virtual machine identifier for the target JVM. The lvmid is a platform-specific value that uniquely identifies a JVM on a system. The lvmid is the only required component of a virtual machine identifier. The lvmid is typically, but not necessarily, the operating system's process identifier for the target JVM process. You can use the jps command to determine the lvmid. Also, you can determine the lvmid on Solaris, Linux, and OS X platforms with the ps command, and on Windows with the Windows Task Manager.

hostname

A hostname or IP address that indicates the target host. If the hostname value is omitted, then the target host is the local host.

port

The default port for communicating with the remote server. If the hostname value is omitted or the protocol value specifies an optimized, local protocol, then the port value is ignored. Otherwise, treatment of the port parameter is implementation-specific. For the default rmi protocol, the port value indicates the port number for the rmiregistry on the remote host. If the port value is omitted and the protocol value indicates rmi, then the default rmiregistry port (1099) is used.

servername

The treatment of the servername parameter depends on implementation. For the optimized local protocol, this field is ignored. For the rmi protocol, it represents the name of the RMI remote object on the remote host.

Options

The jstat command supports two types of options, general options and output options. General options cause the jstat command to display simple usage and version information. Output options determine the content and format of the statistical output.

All options and their functionality are subject to change or removal in future releases.

Output Options

If you do not specify a general option, then you can specify output options. Output options determine the content and format of the jstat command's output, and consist of a single statOption, plus any of the other output options (-h-t, and -J). The statOption must come first.

Output is formatted as a table, with columns that are separated by spaces. A header row with titles describes the columns. Use the -h option to set the frequency at which the header is displayed. Column header names are consistent among the different options. In general, if two options provide a column with the same name, then the data source for the two columns is the same.

Use the -t option to display a time stamp column, labeled Timestamp as the first column of output. The Timestamp column contains the elapsed time, in seconds, since the target JVM started. The resolution of the time stamp is dependent on various factors and is subject to variation due to delayed thread scheduling on heavily loaded systems.

Use the interval and count parameters to determine how frequently and how many times, respectively, the jstat command displays its output.

Note: Do not to write scripts to parse the jstat command's output because the format might change in future releases. If you write scripts that parse jstat command output, then expect to modify them for future releases of this tool.

-statOption

Determines the statistics information the jstat command displays. The following lists the available options. Use the -options general option to display the list of options for a particular platform installation. See Stat Options and Output.

class: Displays statistics about the behavior of the class loader.

compiler: Displays statistics about the behavior of the Java HotSpot VM Just-in-Time compiler.

gc: Displays statistics about the behavior of the garbage collected heap.

gccapacity: Displays statistics about the capacities of the generations and their corresponding spaces.

gccause: Displays a summary about garbage collection statistics (same as -gcutil), with the cause of the last and current (when applicable) garbage collection events.

gcnew: Displays statistics of the behavior of the new generation.

gcnewcapacity: Displays statistics about the sizes of the new generations and its corresponding spaces.

gcold: Displays statistics about the behavior of the old generation and metaspace statistics.

gcoldcapacity: Displays statistics about the sizes of the old generation.

gcmetacapacity: Displays statistics about the sizes of the metaspace.

gcutil: Displays a summary about garbage collection statistics.

printcompilation: Displays Java HotSpot VM compilation method statistics.

-h n

Displays a column header every n samples (output rows), where n is a positive integer. Default value is 0, which displays the column header the first row of data.

-t

Displays a timestamp column as the first column of output. The time stamp is the time since the start time of the target JVM.

-JjavaOption

Passes javaOption to the Java application launcher. For example, -J-Xms48m sets the startup memory to 48 MB. For a complete list of options, see java(1).

Stat Options and Output

The following information summarizes the columns that the jstat command outputs for each statOption.

-class option

Class loader statistics.

Loaded: Number of classes loaded.

Bytes: Number of kBs loaded.

Unloaded: Number of classes unloaded.

Bytes: Number of Kbytes unloaded.

Time: Time spent performing class loading and unloading operations.

-compiler option

Java HotSpot VM Just-in-Time compiler statistics.

Compiled: Number of compilation tasks performed.

Failed: Number of compilations tasks failed.

Invalid: Number of compilation tasks that were invalidated.

Time: Time spent performing compilation tasks.

FailedType: Compile type of the last failed compilation.

FailedMethod: Class name and method of the last failed compilation.

-gc option

Garbage-collected heap statistics.

S0C: Current survivor space 0 capacity (kB).

S1C: Current survivor space 1 capacity (kB).

S0U: Survivor space 0 utilization (kB).

S1U: Survivor space 1 utilization (kB).

EC: Current eden space capacity (kB).

EU: Eden space utilization (kB).

OC: Current old space capacity (kB).

OU: Old space utilization (kB).

MC: Metaspace capacity (kB).

MU: Metacspace utilization (kB).

CCSC: Compressed class space capacity (kB).

CCSU: Compressed class space used (kB).

YGC: Number of young generation garbage collection events.

YGCT: Young generation garbage collection time.

FGC: Number of full GC events.

FGCT: Full garbage collection time.

GCT: Total garbage collection time.

-gccapacity option

Memory pool generation and space capacities.

NGCMN: Minimum new generation capacity (kB).

NGCMX: Maximum new generation capacity (kB).

NGC: Current new generation capacity (kB).

S0C: Current survivor space 0 capacity (kB).

S1C: Current survivor space 1 capacity (kB).

EC: Current eden space capacity (kB).

OGCMN: Minimum old generation capacity (kB).

OGCMX: Maximum old generation capacity (kB).

OGC: Current old generation capacity (kB).

OC: Current old space capacity (kB).

MCMN: Minimum metaspace capacity (kB).

MCMX: Maximum metaspace capacity (kB).

MC: Metaspace capacity (kB).

CCSMN: Compressed class space minimum capacity (kB).

CCSMX: Compressed class space maximum capacity (kB).

CCSC: Compressed class space capacity (kB).

YGC: Number of young generation GC events.

FGC: Number of full GC events.

-gccause option

This option displays the same summary of garbage collection statistics as the -gcutil option, but includes the causes of the last garbage collection event and (when applicable) the current garbage collection event. In addition to the columns listed for -gcutil, this option adds the following columns.

LGCC: Cause of last garbage collection

GCC: Cause of current garbage collection

-gcnew option

New generation statistics.

S0C: Current survivor space 0 capacity (kB).

S1C: Current survivor space 1 capacity (kB).

S0U: Survivor space 0 utilization (kB).

S1U: Survivor space 1 utilization (kB).

TT: Tenuring threshold.

MTT: Maximum tenuring threshold.

DSS: Desired survivor size (kB).

EC: Current eden space capacity (kB).

EU: Eden space utilization (kB).

YGC: Number of young generation GC events.

YGCT: Young generation garbage collection time.

-gcnewcapacity option

New generation space size statistics.

NGCMN: Minimum new generation capacity (kB).

NGCMX: Maximum new generation capacity (kB).

NGC: Current new generation capacity (kB).

S0CMX: Maximum survivor space 0 capacity (kB).

S0C: Current survivor space 0 capacity (kB).

S1CMX: Maximum survivor space 1 capacity (kB).

S1C: Current survivor space 1 capacity (kB).

ECMX: Maximum eden space capacity (kB).

EC: Current eden space capacity (kB).

YGC: Number of young generation GC events.

FGC: Number of full GC events.

-gcold option

Old generation and metaspace behavior statistics.

MC: Metaspace capacity (kB).

MU: Metaspace utilization (kB).

CCSC: Compressed class space capacity (kB).

CCSU: Compressed class space used (kB).

OC: Current old space capacity (kB).

OU: Old space utilization (kB).

YGC: Number of young generation GC events.

FGC: Number of full GC events.

FGCT: Full garbage collection time.

GCT: Total garbage collection time.

-gcoldcapacity option

Old generation size statistics.

OGCMN: Minimum old generation capacity (kB).

OGCMX: Maximum old generation capacity (kB).

OGC: Current old generation capacity (kB).

OC: Current old space capacity (kB).

YGC: Number of young generation GC events.

FGC: Number of full GC events.

FGCT: Full garbage collection time.

GCT: Total garbage collection time.

-gcmetacapacity option

Metaspace size statistics.

MCMN: Minimum metaspace capacity (kB).

MCMX: Maximum metaspace capacity (kB).

MC: Metaspace capacity (kB).

CCSMN: Compressed class space minimum capacity (kB).

CCSMX: Compressed class space maximum capacity (kB).

YGC: Number of young generation GC events.

FGC: Number of full GC events.

FGCT: Full garbage collection time.

GCT: Total garbage collection time.

-gcutil option

Summary of garbage collection statistics.

S0: Survivor space 0 utilization as a percentage of the space's current capacity.

S1: Survivor space 1 utilization as a percentage of the space's current capacity.

E: Eden space utilization as a percentage of the space's current capacity.

O: Old space utilization as a percentage of the space's current capacity.

M: Metaspace utilization as a percentage of the space's current capacity.

CCS: Compressed class space utilization as a percentage.

YGC: Number of young generation GC events.

YGCT: Young generation garbage collection time.

FGC: Number of full GC events.

FGCT: Full garbage collection time.

GCT: Total garbage collection time.

-printcompilation option

Java HotSpot VM compiler method statistics.

Compiled: Number of compilation tasks performed by the most recently compiled method.

Size: Number of bytes of byte code of the most recently compiled method.

Type: Compilation type of the most recently compiled method.

Method: Class name and method name identifying the most recently compiled method. Class name uses slash (/) instead of dot (.) as a name space separator. Method name is the method within the specified class. The format for these two fields is consistent with the HotSpot -XX:+PrintCompilation option.

Examples

This section presents some examples of monitoring a local JVM with an lvmid of 21891.

The gcutil Option

This example attaches to lvmid 21891 and takes 7 samples at 250 millisecond intervals and displays the output as specified by the -gcutil option.

The output of this example shows that a young generation collection occurred between the third and fourth sample. The collection took 0.078 seconds and promoted objects from the eden space (E) to the old space (O), resulting in an increase of old space utilization from 66.80% to 68.19%. Before the collection, the survivor space was 97.02% utilized, but after this collection it is 91.03% utilized.

jstat -gcutil 21891 250 7
  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT   
  0.00  97.02  70.31  66.80  95.52  89.14      7    0.300     0    0.000    0.300
  0.00  97.02  86.23  66.80  95.52  89.14      7    0.300     0    0.000    0.300
  0.00  97.02  96.53  66.80  95.52  89.14      7    0.300     0    0.000    0.300
 91.03   0.00   1.98  68.19  95.89  91.24      8    0.378     0    0.000    0.378
 91.03   0.00  15.82  68.19  95.89  91.24      8    0.378     0    0.000    0.378
 91.03   0.00  17.80  68.19  95.89  91.24      8    0.378     0    0.000    0.378
 91.03   0.00  17.80  68.19  95.89  91.24      8    0.378     0    0.000    0.378

Repeat the Column Header String

This example attaches to lvmid 21891 and takes samples at 250 millisecond intervals and displays the output as specified by -gcnew option. In addition, it uses the -h3 option to output the column header after every 3 lines of data.

In addition to showing the repeating header string, this example shows that between the second and third samples, a young GC occurred. Its duration was 0.001 seconds. The collection found enough active data that the survivor space 0 utilization (S0U) would have exceeded the desired survivor Size (DSS). As a result, objects were promoted to the old generation (not visible in this output), and the tenuring threshold (TT) was lowered from 31 to 2.

Another collection occurs between the fifth and sixth samples. This collection found very few survivors and returned the tenuring threshold to 31.

jstat -gcnew -h3 21891 250
 S0C    S1C    S0U    S1U   TT MTT  DSS      EC       EU     YGC     YGCT
  64.0   64.0    0.0   31.7 31  31   32.0    512.0    178.6    249    0.203
  64.0   64.0    0.0   31.7 31  31   32.0    512.0    355.5    249    0.203
  64.0   64.0   35.4    0.0  2  31   32.0    512.0     21.9    250    0.204
 S0C    S1C    S0U    S1U   TT MTT  DSS      EC       EU     YGC     YGCT
  64.0   64.0   35.4    0.0  2  31   32.0    512.0    245.9    250    0.204
  64.0   64.0   35.4    0.0  2  31   32.0    512.0    421.1    250    0.204
  64.0   64.0    0.0   19.0 31  31   32.0    512.0     84.4    251    0.204
 S0C    S1C    S0U    S1U   TT MTT  DSS      EC       EU     YGC     YGCT
  64.0   64.0    0.0   19.0 31  31   32.0    512.0    306.7    251    0.204

Include a Time Stamp for Each Sample

This example attaches to lvmid 21891 and takes 3 samples at 250 millisecond intervals. The -t option is used to generate a time stamp for each sample in the first column.

The Timestamp column reports the elapsed time in seconds since the start of the target JVM. In addition, the -gcoldcapacity output shows the old generation capacity (OGC) and the old space capacity (OC) increasing as the heap expands to meet allocation or promotion demands. The old generation capacity (OGC) has grown from 11,696 kB to 13,820 kB after the eighty-first full garbage collection (FGC). The maximum capacity of the generation (and space) is 60,544 kB (OGCMX), so it still has room to expand.

Timestamp      OGCMN    OGCMX     OGC       OC       YGC   FGC    FGCT    GCT
          150.1   1408.0  60544.0  11696.0  11696.0   194    80    2.874   3.799
          150.4   1408.0  60544.0  13820.0  13820.0   194    81    2.938   3.863
          150.7   1408.0  60544.0  13820.0  13820.0   194    81    2.938   3.863



source - https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstat.html





Java Platform, Standard Edition Tools Reference
Contents    Previous    Next


jstatd

Monitors Java Virtual Machines (JVMs) and enables remote monitoring tools to attach to JVMs. This command is experimental and unsupported.

Options

-nr

Does not attempt to create an internal RMI registry within the jstatd process when an existing RMI registry is not found.

-p port

The port number where the RMI registry is expected to be found, or when not found, created if the -nr option is not specified.

-n rminame

Name to which the remote RMI object is bound in the RMI registry. The default name is JStatRemoteHost. If multiple jstatd servers are started on the same host, then the name of the exported RMI object for each server can be made unique by specifying this option. However, doing so requires that the unique server name be included in the monitoring client's hostid and vmid strings.

-Joption

Passes option to the JVM, where option is one of the options described on the reference page for the Java application launcher. For example, -J-Xms48m sets the startup memory to 48 MB. See java(1).

Security

The jstatd server can only monitor JVMs for which it has the appropriate native access permissions. Therefore, the jstatd process must be running with the same user credentials as the target JVMs. Some user credentials, such as the root user in Solaris, Linux, and OS X operating systems, have permission to access the instrumentation exported by any JVM on the system. A jstatd process running with such credentials can monitor any JVM on the system, but introduces additional security concerns.

The jstatd server does not provide any authentication of remote clients. Therefore, running a jstatd server process exposes the instrumentation export by all JVMs for which the jstatd process has access permissions to any user on the network. This exposure might be undesirable in your environment, and therefore, local security policies should be considered before you start the jstatd process, particularly in production environments or on networks that are not secure.

The jstatd server installs an instance of RMISecurityPolicy when no other security manager is installed, and therefore, requires a security policy file to be specified. The policy file must conform to Default Policy Implementation and Policy File Syntax at
http://docs.oracle.com/javase/8/docs/technotes/guides/security/PolicyFiles.html

The following policy file allows the jstatd server to run without any security exceptions. This policy is less liberal than granting all permissions to all code bases, but is more liberal than a policy that grants the minimal permissions to run the jstatd server.

grant codebase "file:${java.home}/../lib/tools.jar" {   
    permission java.security.AllPermission;
};

To use this policy setting, copy the text into a file called jstatd.all.policy and run the jstatd server as follows:

jstatd -J-Djava.security.policy=jstatd.all.policy

For sites with more restrictive security practices, it is possible to use a custom policy file to limit access to specific trusted hosts or networks, though such techniques are subject to IP address spoofing attacks. If your security concerns cannot be addressed with a customized policy file, then the safest action is to not run the jstatd server and use the jstat and jps tools locally.

Examples

The following are examples of the jstatd command. The jstatd scripts automatically start the server in the background



source - https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstatd.html





'Development > Java' 카테고리의 다른 글

ClassLoader 문제 분석  (0) 2012.02.02
BTrace  (0) 2012.02.02
java.lang.OutOfMemoryError: PermGen space  (0) 2012.02.02
스윙(Swing)  (0) 2012.01.30
JCA(Java EE Connector Architecture)  (0) 2012.01.27
Posted by linuxism
,

Heap

The Java virtual machine heap is the area of memory used by the JVM (and specifically HotSpot) for dynamic memory allocation.[10] The heap is split up into "generations":

  • The young generation stores short-lived objects that are created and immediately garbage collected.
  • Objects that persist longer are moved to the old generation (also called the tenured generation).
  • The permanent generation (or permgen) is used for class definitions and associated metadata.[11][12]

Originally there was no permanent generation, and objects and classes were stored together in the same area. But as class unloading occurs much more rarely than objects are collected, moving class structures to a specific area allows significant performance improvements.[11] 


source -  http://en.wikipedia.org/wiki/Java_virtual_machine 










How do you determine a good MaxPermSize?에서 Matt 가 OOM(OutOfMemory) 에러에 시달리는데, -Xmx 사이즈를 아무리 늘려도 해결이 안됐었나 보다.

설명에 의하면 클래스의 메타 정보는 -Xmx 로 지정되는 메모리 영역이 아닌 MaxPermSize로 지정되는 메모리 영역에 들어간다고 한다.

헌데, 요즘, Spring, iBatis, Hibernate 같은 리플렉션을 이용해서 클래스 메타 정보를 가져다 쓰는 프레임워크들이 많아지면서, MaxPermSize 를 기본값으로 놓고 사용하면 메모리가 부족해지는 현상이 일어나나 보다(나는 아직 겪어보지 못했다).

-XX:PermSize=64m -XX:MaxPermSize=256m


위와 같이 MaxPermSize를 지정하면 된다.

근데, 댓글들을 읽어보면 256m 은 좀 오바인것 같고, OOM 오류가 발생하면 테스트를 해가면서 세팅해야 할 것 같다.

기본 값은 JVM이 -client 옵션의 경우에는 32m -server 옵션일 경우에는 64m 이라고 한다.

또한, MaxPermSize는 -Xmx 로 지정한 메모리 용량과 별도로 할당된다. 즉, -Xmx가 256m 이고, -XX:MaxPermSize가 256m 이라면, 최대 512m이 할당될 수 있다는 것이다.

MaxPermSize and how it relates to the overall heap에 MaxPermSize에 대한 더 자세한 내용이 있다.
JAVA(J2SE 1.4.1) 메모리 영역 구조도 함 읽어보자. 


출처 -  http://kwon37xi.egloos.com/2368729 








이번에는 Heap dump를 통해 분석할 수 있는 경우로 Permanent 영역 Full 문제를 분석하는 방법에 대해 사례를 통해 알아 보도록 하겠습니다.
이전 포스트에서 설명드렸듯이 Permanent 영역은 Class의 메타정보들이 저장되는 영역이며, 이는 JVM에서 class 정보를 토대로 메모리 상에 object로 생성할 때 효과적으로 빠르게 생성하기 위해 저장하는 것입니다.
Permanent 영역 Full도 일종의 OutOfMemoryError의 한 종류이며, 설정한 Permanent 영역의 크기보다 더 많은 class들을 사용하고 있을 경우 발생할 수 있읍니다. 또한 잘못된 Custom ClassLoader 구현으로 인해 중복된 class 정보들이 해제되지 못하고 지속적으로 메모리를 잠식하는 경우가 있습니다.
Permanent 영역의 크기보다 더 많은 class들을 사용하고 있을 경우는 Permanent 영역의 크기를 늘려주기만 하면 됩니다. 그러나 그렇지 않은 경우는 문제를 분석하여 어느 부분에서 해제를 못하고 있는지를 확인해야 합니다.
바로 이부분이 이번 포스트에서 다룰 내용입니다. 
사실 이러한 문제는 해결하는 것이 그렇게 쉽지는 않습니다. 제가 이번 포스트에서 설명드릴 사례도 정확하게 어느 부분에서 문제가 발생하였는지 확인하지 못한 경우입니다. 저의 능력이 거기까지 였던거 같습니다. ㅠ.ㅠ!
Permanent 영역 Full 오류가 발생하면 다음과 같은 오류가 로그파일에 출력됩니다.


그럼 지금부터 Permanent Generation Full 오류 문제를  Heap dump를 통해 분석하는 방법에 대해 사례를 통해 알아 보도록하겠습니다.
분석 방법에 대한 이해를 높이기 위해 분석 사례의 오류 발생 상황에 대해 먼저 설명드리도록 하겠습니다.


정상적이라면 Custom ClassLoader가 하나만 생성되어 있어야 하지만 동일한 Custom ClassLoader가 여러개 생성되어 동일한 class의 메타 정보가 여러 Custom ClassLoader에 중복 생성됨으로써 Permanent 영역의 공간을 차지하고 있는 경우입니다.

그럼 해당 Heap dump를 HeapAnalyzer 툴을 통해 분석해 보도록 하겠습니다.


위와 같이 Heap dump 파일을 HeapAnalyzer에서 열게 되면 reference tree와 함께 leak suspect 부분이 나타납니다.
그러나 Permanent 영역 Full 인 경우는 이 leak suspect가 OutOfMemoryError에서와 다르게 확인하는 것이 의미가 없습니다.


위의 그림과 같이 Permanent 영역 Full이 발생할 경우는 class 정보의 중복 여부를 확인하기 위해 Type 리스트 보기를 선택합니다.
그리고 Type 리스트에서 "Type" 즉 class 명을 클릭하여 정렬하고 class 들의 중복 여부를 확인합니다.
정상적인 경우는 동일한 class에 대한 정보는 하나의 row에 count 수(class 한개와 object 여러개)만 집계되지만 위의 경우는 동일한 class에 대해 다수의 row가 집계되어 보여지는 것을 알 수 있습니다. 이는 Type 리스트의 개별 row는 하나의 class에 대한 메모리 address로 생성됩니다. 따라서 동일한 class에 여러개의 row가 있다는 것은 하나의 class가 다른 메모리 address를 가지고 존재하고 있다는 것입니다.
즉, class가 변경되었거나 하였을때 제대로 해제되지 않았다고 볼 수 있는데요. 이렇게 동일한 class가 각각 다른 메모리 address에 존재한다는 것은 해당 class를 로드한 ClassLoader가 class의 메모리 address 수만큼 여러개일 확률이 높습니다.
그럼 동일한 class중 하나를 오른쪽 마우스 click하여 "Find same type"을 통해 확인해 보도록 하겠습니다.
 

위와 같이 해당 class에 대한 동일 type의 리스트를 확인해 보면 동일한 class가 3개 존재하고 있는 것을 확인할 수 있습니다.
그 아래로는 class를 토대로 생성된 object들이 3개가 있는 것을 확인할 수 있습니다. 이 object 들이 하나의 class를 토대로 만들어 졌는지 아니면 각각의 class에 대해 하나씩 object가 생성된 것인지는 알 수는 없지만, 동일한 class가 3개가 있다는 것으로도 ClassLoader상에 문제가 있어 Permanent 영역이 언제 Full 날지 모르는 상황인것 만은 분명한 것으로 보여집니다.
그럼 각 class들에 대해 오른쪽 마우스 click하여 "Find object in tree view" 선택하여 reference tree상에서 해당 class의 위치와 계층을 확인해 보도록 하겠습니다.


해당 class를 reference tree에서 확인해 보면 다른 업무 class들의 리스트가 존재하는 것을 확인할 수 있습니다.
그럼 이러한 class들이 속해있는 parent object를 확인해 보면 위의 그림과 같이 Custom ClassLoader내에 있는 것을 알 수 있습니다.  이번 사례의 Custom ClassLoader는 개발 프레임웍인 Proframe의 ProframeChangeAwareClassLoader 입니다.
각 class들이 모두 동일한 ClassLoader에 포함되어 있는지 아니면 각각 별개의 ClassLoader에 포함되어 있는지를 확인하기 위해 각 class들을 위와 동일하게 확인하면 각각 다른 Custom ClassLoader 객체에 포함되어 있는 것을 확인할 수 있습니다.

그럼 각 Custom ClassLoader들이 어느 위치에 존재하는지 parent 객체를 확인하고 계층을 확인해 보도록 하겠습니다.


위의 그림과 같이 3개의 Custom ClassLoader 중 2개는 동일한 object 계층구조를 가지고 있으나, 나머지 하나는 다른 계층 구조를 가지고 있는 것을 알 수 있습니다.
그럼 무엇이 다른지 확인해 보도록 하겠습니다. 
세개 중 다른 계층 구조를 갖는 Custom ClassLoader는 정상적인 것을 보여집니다. ClassLoader가 가져야할 계층 구조(Thread --> AppClassLoader --> ContextFactory --> Custom ClassLoader ...)이나 나머지 두개는 AS400과 관련된 객체(IBM Toolbox for java)를 parent로 가지고 있는 것을 알 수 있습니다.
AS400 관련 객체는 AS400 장비의 DB2 데이타베이스와 연동하기 위한 JDBC Driver라고 할 수 있습니다.
AS400 관련 객체가 Custom ClassLoader(ProframeChangeAwareClassLoader)를 생성하거나 참조할 경우는 없을 것 같으니 이러한 계층구조를 갖게된 것은 역참조에 의한 부분으로 보여집니다.
이러한 현상은 Hot-deploy 수행 시 Custom ClassLoader가 해제되지 않고 계속 존재하여 동일한 class들이 ClassLoader로 로드되어 Permanent 영역 Full이 나는 것입니다.
Custom ClassLoader가 해제되지 않고 존재하는 원인을 밝히기 위해서는 Custom ClassLoader와 AS400 관련 class 간의 관계를 파악할 필요가 있습니다.  그뿐 아니라 AP들과의 관계(AP 처리 flow등)도 같이 분석해야 하는 굉장히 어려운 분석 작업을 수행해야 합니다.

이번 사례는 소프트웨어 제품에 대한 분석인 관계로 접근도 용이하지 않고 분석할 수 있는 데이터도 제한이 있어 끝내 밝히지 못했던 사례입니다. 물론 벤더의 개발자가 직접 확인을 했으나 뚜렸한 원인을 파악히지 못한 경우 였습니다.
그러나 유력한 원인으로 유추해 볼 수 있는 부분은 AS400(IBM Toolbox for java) 연계 방식이 일반 JDBC와 다르게 처리 결과 응답을 별도의 응답 Thread가 기동하여 수신 처리한다는 것이며 이러한 Thread가 AS400과의 Connection 이 끊어지기 전까지는 종료되지 않으므로 이 Thread 에서 Custom ClassLoader과 관리하는 Data 관련 객체들을 사용하게 되면 Custom ClassLoader의 역참조가 발생하는 것이 아닌가 하는 것입니다. 물론 아닐 수도 있겠지만 ㅠ.ㅠ!
사례에 대해 깔끔한 원인 분석은 이루어지지 않았지만 여기까지가 저의 한계라고 생각하며 사례에 대한 부분은 마치도록 하겠습니다. 

그리고 지금 부터는 번외로 ClassLoader에 대해 간단히 설명을 드리도록 하겠습니다.(이후 포스트에서 자세히 다룰 예정입니다.)

다음은 ClassLoader와 Permanent 영역간의 관계에 대한 이해를 위해 Custom ClassLoader와 class 메타 정보가 저장되는 Vector 객체에 대한 그림입니다.


앞의 사례에서 Custom ClassLoader는 실제로 class  메타 정보를 저장하기 위해 JDK의 ClassLoader를 상속받아 구현하게 됩니다. ClassLoader 객체내에 Vector가 있으며 이 Vector가 class들의 저장소 역할을 하며 이 Vector의 내용을 확인하여 class가 이미 로드되었는지 아닌지를 확인하게 됩니다.
그럼 Custom ClassLoader는 무슨 기능을 할까요? 말 그대로 각종 ClassLoader의 기능을 구현하는 것입니다. 예를 들어 class cache 기능 또는 class 변환 기능 등 다양한 기능을 class를 로드하기 전이나 후에 수행할 수 있습니다.
이렇게 Custom ClassLoader는 ClassLoader를 상속받아 구현되며, Permanent 영역 Full이 발생할 경우 Custom ClassLoader내에는 아래와 그림과 같이 Vector 객체에 class들이 위치하는 것은 일반적인 현상입니다.


이상으로 Permanent 영역 Full 문제를 Heap dump를 통해 분석해 보았습니다.
다음에는 Heap 메모리 Leak에 대해 알아볼까 생각중입니다.
그럼 모두들 즐거운 일상되시기 바랍니다.



출처 -  http://blog.naver.com/bumsukoh?Redirect=Log&logNo=110125469644 









메모리 누수 leak 를 알게 되는 일반적인 방법 중 하나가 java.lang.OutOfMemoryError 에러 입니다. 이 에러는 Java 힙 heap 이나 힙의 특정 영역에 객체를 할당 할 수 있는 공간이 충분하지 않을 때 발생합니다.

PermGen space 라는 메시지는 permanent generation 이 가득 찬 상태라는 것을 알려줍니다. permanent generation 은 클래스와 메쏘드 객체가 저장되는 힙의 영역입니다. 어플리케이션이 많은 수의 클래스를 로드하면, -XX:MaxPermSize 옵션을 사용하여 permanent generation 의 크기를 증가시킬 필요가 있습니다.

톰캣 Tomcat 을 사용하다 이 에러를 보았다면 대체로 웹 어플리케이션을 너무 많이 Update 하거나 Reload 한 것이 원인입니다. 톰캣 과 JVM 은 웹 어플리케이션을 삭제하고 다시 생성할 때 할당한 모든 메모리를 해제하지는 않습니다. 톰캣을 여러 번 리로드하면 할당된 메모리가 바닥나서 동작하지 않게 됩니다.

톰캣에서 이 에러가 발생했을 때 해결 방법은
1. 톰캣을 재시작하는 것입니다.
2. 톰캣이 할당할 수 있는 메모리를 늘려줄 수도 있습니다. 이 방법은 에러 발생을 중지시키는 것이 아니라 톰캣을 재시작하기까지의 시간을 연장시킬 뿐입니다.
3. 메모리 누수가 발생하지 않도록 톰캣을 설정합니다.
Java Heap 크기 증가

커맨드라인으로 톰캣을 실행시킨다면 아래의 파라미터를 추가합니다.
-Xmx512m -Xms512m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:NewSize=128m

윈도우 서비스로 톰캣을 실행시킨다면 톰캣 모니터를 실행시키고, Tomcat -> Java -> Java Options 에 아래의 내용을 추가합니다. 
-Xmx512m -Xms512m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:NewSize=128m
참고1: 복사해서 붙여넣기를 할 때 빈 공간이 추가되지 않도록 주의하십시오. 톰캣을 시작하지 못할 수 있습니다.
참고2: 64비트 버전의 톰캣을 사용한다면 레지스트리 HKEY_LOCAL_MACHINE\SOFTWARE\Apache Software Foundation\Procrun 2.0\Tomcat5\Parameters\JavaJVM 을 변경해야 합니다.

리눅스 linux 나 유닉스 unix 환경에서 톰캣 tomcat 을 사용하시면 catalina.sh 파일의 상단에 아래의 문장을 추가해 주면 됩니다. 필요에 따라 서버의 swap 영역을 넓혀줍시다.
JAVA_OPTS="-Djava.awt.headless=true -server -Xms512m -Xmx1024m -XX:NewSize=256m -XX:MaxNewSize=256m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:+DisableExplicitGC"

메모리 누수 방지 설정

conf/web.xml file 파일에서 jsp 서블릿 부분에 아래의 내용을 추가합니다.
<init-param>
  <param-name>enablePooling</param-name>
  <param-value>false</param-value>
</init-param>


다른 옵션에 대해서는 천천히 설명하도록 하겠습니다. 

출처 - http://mindasom.tistory.com/96










출처 : http://www.javaservice.net/~java/bbs/read.cgi?b=was&c=r_p&m=appserver&n=1076057072

제목 : MaxPermSize 관련 문제
글쓴이: 최우석(guest) 2004/02/06 17:44:32 조회수:1572 줄수:26
안녕하세요.

현재 HP-UX 11.0에서 운영하고 있는 WAS 3.5에서 

Permanent generation is full...
Increase MaxPermSize (current capacity is set to: 32768K )

위와 같은 에러가 나고 있습니다.

이런 에러가 나면 서버가 Hang 걸리면서 응답이 없어져서 리스타트를 해야만 합니다.

관련 문서를 찾아보니,
jvm parameter를 추가적으로 설정해 줘야한다고 하는군요.
(보시다시피 default가 32메가인 것 같습니다.)

그래서 -XX:MaxPermSize=<size>를 추가해주려고 하는데,
얼마나 설정해 줘야할 지 모르겠습니다.
ibm 문서를 검색해 봐도 HP 에서 얼마를 설정해줘라하는 문서는 못 찾겠습니다.

도움이 될만한 문서로는,
solaris에 WAS 4.0 깔 때 64m로 설정하라는 게 있었고,
WPS에서는 128m로 하라는 게 있었구요,
Xmx(현재 512m)보다 작아야한다는 것도 있었습니다만, 
정확한 guideline은 없더군요.

이럴 때 어떻게 하면 좋을까요?
제목 : Re: 운영중에 발생한 문제라면..
글쓴이: 손님(guest) 2004/02/09 11:33:26 조회수:841 줄수:28
 Perm Size(Permanant Area라고 하던가요?)는 보통 WAS나 JVM이 사용하는 
 Class들이 사용하는 공간입니다.
 보통 WAS를 처음 구동시킬때 위와 같은 에러가 발생하면, Class를 로딩시킬
 메모리 공간이 부족하는 의미이며, 이때는 MaxPermSize를 어느정도 크게 잡아서 
 재 구동시키면 됩니다.

 근데, 문제는 위와 같이 운영중인 서버에서 해당 에러를 발생시키고 죽는 경우입니다.
 사실 이론적으로는 운영중일때는 위와 같은 에러메시지를 내지 말아야 하지만,
 제가 추측하건데.. 다음의 경우에 발생할 수 있는듯 합니다.

 첫번째는 해당 WAS의 버그때문에 운영중에 Class를 로딩을 계속 시키는 경우입니다.
 모 사이트에서 모 WAS의 버그를 확인한 적이 있습니다.
 그때, JSP를 .java 파일로 바꾸고 다시 컴파일하고 Class 로딩하는 WAS의 작업에 
 버그가 있어서, 특정 JSP에서 변환된 .class 파일이 계속 클래스로딩되었던 적이
 있습니다. 이때 개발쪽하고 WAS 업체하고 말이 많았는데, 결국 WAS쪽 버그로 판명
 되었습니다.

 그리고, 위의 경우가 아니라면, 혹시 서비스 하는 모듈 중에 Class 로딩을 계속 
 수행하고 있는 것이 있는지 확인해 보십시오.
 JSP 파일 자체가 계속 수정된다거나.. 인위적으로 특정 Class를 로딩시킨다던가..

 아무튼, 제가 아는 바로는 운영중에 위와같은 에러가 발생한다는것은 
 MaxPermSize를 아무리 크게 잡아줘도 언젠가는 다시 발생할 수 있다는 것을 말합니다.
 
 저도 이 부분에 대해 확실히 알고 싶은데, 정보가 잘 없더군요.
 더 잘 아시는분이 있으시면 좋겠네요.


출처 - http://bambabo.blog.me/120137349324











이클립스 java.lang.OutOfMemoryError: PermGen space 에러시

JVM메모리는 Java Heap space, Permanent Generation 이 존재합니다.

PermGen space는 JVM에서 관리하는 메모리 영역중 하나입니다.

Heap space는 프로그램 실행 도중 생성삭제 되는 Garbage-collected(필요없는경우 제거)입니다.

Permanent는 프로그램이 종료될때 까지 메모리를 차지하는 공간입니다.

Heap은 동적으로 메모리를 사용하게 되며 Permanent는 Class Names, internalized strings, Object등이 들어가며

PermGen도 이곳에 해당합니다.

 

java.lang.OutOfMemoryError: PermGen space의 해결책은 이클립스 실행시 메모리를 늘려주면 됩니다.

기본은 20M로 설정이 됩니다.

 

1. eclipse.ini 파일 설정.

    javaw -vmargs -Xverify:none -XX:+UseParallelGC -XX:PermSize=64M -XX:MaxPermSize=128M -XX:MaxNewSize=32M -XX:NewSize=32M -Xmx512M

 

2. eclipse실행 파일.

   C:\eclipse\eclipse-jee-ganymede-SR1-win32\eclipse\eclipse.exe -vm "C:\Program Files\Java\jre6\bin\javaw" -vmargs -XX:MaxPermSize=128m -Xms128m -Xmx512m

 

3. eclipse의 Java VM 옵션 용량 수정.

   eclipse 사용시 : Window > Preferences > java > installend JREs > 사용중인 JRE선택 > edit > Default VM Arguments

   기본방식

  -XX:MaxPermSize=Permanent Generation의 최대용량(기본 용량은 64MB)

   변경설정

  -XX:MaxPermSize=128m

 

-출처 : Length 카페  












이클립스에서 잘 돌아가고 있는데 콘솔 창에 심각! 이러면서 java.lang.OutOfMemoryError: PermGen space 에러가 발생하기 시작...기분 나쁜 빨간색과 띄어쓰기로 가지런히 줄지어 있는 에러들...

찾아보니 ..

'Java는 메모리 영역을 사실상 두 부분으로 구분하여 사용한다. 일반 Java Heap space와 클래스와 같이 Permenant Generation 대상 데이터를 두기 위한 PermGen space이다.
대부분의 자바 애플리케이션에서는 기본 PermGen Size로 충분하겠지만 이클립스의 경우 클래스가 꽤 많아지면서 모자란 경우가 있는듯 하다" 
 - http://purehani.egloos.com/1593651


## 원인
Permanent Generation(VM이 데이터를 가지는 곳 중 하나)의 용량 부족.

## 대처
Java VM 기동 옵션에서 용량을 늘려준다.
(Eclipse의 경우는 Window->Preferences->java->installed JREs->사용중인 JRE선택 후 Edit->
Default VM Arguments에서 설정해주면 된다.)
= 기본 방식

-XX:MaxPermSize=Permanent Generation의 최대용량(기본 용량은 64MB)


= 실제 설정 시 (m은 MB)

-XX:MaxPermSize=128m


위와 같이 설정하도록 하자.

-XX:PermSize (Permanent Generation의 초기용량)을 -XX:MaxPermSize와 같은 용량으로 하는 설정도 있긴하지만 너무 적당적당히 늘려버리면 메모리 할당 균형에 문제가 생기므로 주의하자.
Permanent Generation이 부족한 경우에는 -Xmx의 사이즈도 늘리는게 좋을지도 모름


출처 - 
http://netholic.tistory.com/59 










요즘 들어 부쩍 java.lang.OutOfMemoryErorr로 인해 이클립스가 뻗어버리는 일이 많이 발생했었다. 하지만 Heap Monitor를 보면 200M 조차 사용하지 않는다. 이런 경우, 대부분은 PermGen 영역이 모자란 것이 원인일 수 있다.

{workspace}/.metadata/.log를 확인해보면 PermGen space라고 기록되어 있을 것이다.

Eclipse를 사용할 때는 JVM에 -Xmx 옵션은 대부분은 넣어서 사용하리라 생각한다. 하지만 Java는 메모리 영역을 사실상 두 부분으로 구분하여 사용한다. 일반 Java Heap space와 클래스와 같이 Permenant Generation 대상 데이터를 두기 위한 PermGen space이다.

대부분의 자바 애플리케이션에서는 기본 PermGen Size로 충분하겠지만 이클립스의 경우 클래스가 꽤 많아지면서 모자란 경우가 있는듯 하다. javanese의 경우 Callisto를 깔아놓고 JDT, CDT를 왔다갔다 하면서 사용하다보니 Heap은 별로 쓰지도 않는데 PermGen space가 종종 모자라는 경우가 있다. 아마 Web관련 Tool을 많이 사용하는 분도 같은 현상이 나타날 수 있을 것이다.

PermGen space는 -XX:MaxPermSize 옵션으로 설정할 수 있다.

eclipse -vm /usr/lib/jvm/java-1.5.0-sun/bin/java -vmargs -XX:MaxPermSize=128m -Xms128m -Xmx512m

OutOfMemory 에러가 발생한다면 -Xmx만 늘려주지말고 PermSize도 확인해보라.
 


클래스 갯수가 주요원인이기보다는 최근에 framework들이 reflection을 많이 사용해서 더 큰 perm size가 꽤 필요합니다. 이클립스뿐만 아니라, WAS에도 사이즈를 늘려줘야 합니다. 


출처 - 
http://purehani.egloos.com/1593651 






Posted by linuxism
,