달력

12025  이전 다음

  • 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

SQL loader 사용하기

DB 2008. 9. 19. 16:46

>> SQL*loader <<

  SQL*Loader는 외부 화일의 데이타를 ORACLE  데이타베이스의 테이블에 넣기 위한 유틸리티이다.  SQL*loader를 사용하려면 외부 데이타 화일과 콘트롤화일이 필요하다.    
  콘트롤화일이라고 하는 것은 로드하는 데이타의 정보를 저장한 화일인데 예를 들면 다음과 같다.

   load data          ->  콘트롤화일의 앞에는 반드시 필요함
   infile sample.dat    ->  외부 데이타 화일을 지정
   replace             ->  테이블에 데이타 넣는 방법 지정
   into table TABLE_NAME -> 데이타를 로드하는 테이블을 지정
   fields terminated by ','    ->  데이타 필드의 종결문자 지정
   (a integer external,b char) ->  테이블의 열 및 외부데이타
                                     화일의 데이타 형을 지정
                            
    *참고로 Replace 외에 다음의 옵션이 가능하다.

   replac   -> 테이블의 기존 행을 모두 삭제(delete)하고
                 Insert(7.0 에서는 truncate 함)
   append  -> 새로운 행을 기존의 데이타에 추가
   insert   -> 비어 있는 테이블에 넣을 때
   truncate -> 테이블의 기존 데이타를 모두 truncate 하고 인서트
               (7.0에는 없음)
  
  SQL*loader를 실행하면 아래의 화일이 생성된다.
  -  로드 작업의 결과와 에러 등을 기록한 로그화일(확장자는 log)  
  -  에러 때문에 로드가 안된 레코드를 저장한 화일(확장자는 bad)
  -  사용자의 선택 기준에 적합하지 않은 레코드를 저장한 파일
     (discard 화일)
      이것은 discardfile 옵션으로 별도로 지정해야 생성된다.
실행 방법

  $ sqlload scott/tiger control=sample.ctl data=sample.dat

  1. 임의의 컬럼에 문자열(값)을 입력한 경우

   [ 테이블 구조 ]
   create table cons_test
   (a number,  b number,    c number,    d varchar(10))

   [ 콘트롤 화일 ]
   load data
   infile cons.dat
   replace
   into table cons_test
   fields terminated by ','
   (a integer external,
    b integer external,
    c CONSTANT '100',
    d char)

   [ 외부 데이타 파일 cons.dat의 내용 ]
   1,2,DATA
   2,4,DATA2

   [ 검색결과 ]
   SQL> select * from cons_test;
       A       B       C    D
     ------- ----- ------ ------------
       1       2     100   DATA
       2       4     100   DATA2


  2. 로드한 때의 날짜를 넣고 싶은 경우

   [ 테이블 구조 ]
   create table sysdatetb
   (a number,    b date,    c varchar(10))

   [ 콘트롤 화일 ]
   load data
   infile sysdate2.dat
   replace
   into table sysdatetb
   fields terminated by ','
   (a integer external,
    b sysdate,
    c char(10))

   [ 외부 데이타 화일 ]
   111,STRINGS
   222,STRINGS2

   [ 검색결과 ]
   SQL> select * from sysdatetb;
        A         B           C
     -------  ---------  ----------
      111    13-MAY-94    STRING
      222    13-MAY-94    STRING2

SYSDATE는 Conventional Path의 경우는  실행시에 삽입된 각각의 레코드 배열마다, Direct Path의 경우는 로드된 각각의 레코드의 블록마다 사용된다. 새로운 값으로 변경된다.

 

  3. SEQUENCE를 임의의 수에서 임의의 수만큼 붙이고 싶은 경우

   [ 테이블 구조 ]
   create table seqtb
   (a varchar(10),    b number,    c varchar(10))

   [ 콘트롤 화일 ]
   load data
   infile seq.dat
   replace
   into table seqtb
   fields terminated by ','
   (a char,
    b sequence(100,5),
    c char)

   [ 외부 데이타 화일 ]
    1,a
    2,b
    3,c

   [ 검색결과 ]
   SQL> select * from seqtb;
     A    B     C
   ----- ---- --------
    1    100    a
    2    105    b
    3    110    c

 

  4. 논리 레코드를 구성하는 물리 레코드가 여러줄로 구성된 경우
     (물리 레코드의 1바이트째로 판단되는 경우)

  [ 테이블 구조 ]
  create table conti_test
  (a varchar(10),   b varchar(10),   c varchar(10))

  [ 콘트롤 화일 ]
  load data
  infile conti.dat
  replace
  continueif this  (1) = '%'
  into table conti_test
  fields terminated by ','
  (a char,
   b char,
   c char)

  [ 외부 데이타 화일 ]
  %1,
  %2,
  3
  %A,B
  ,C
  %a,b
  %c
  %d
  ,ef

 

 

  [ 검색결과 ]

  SQL> select * from conti_test;

  A      B       C
---- ------ --------
  1      2       3
  A      B       C
  a      bcd     ef

  이 예의 경우 1바이트 째가 계속 행의 체크를 위해서 사용되기 때문에 실제의 데이타를 1바이트 째부터 시작해서는 안된다.
위의 경우, 레코드의 선두 바이트가 '%'일 때 다음의 레코드가 연결된다.

 


  5. 외부데이타 화일의 물리 레코드가 복수 레코드로 구성된 경우
     (구성하는 물리 레코드 수가 모두 일정한 경우)

  [ 테이블 구조 ]
  create table con_test  
  (a varchar(10),   b varchar(10),   c varchar(10))

  [ 콘트롤 화일 ]
  load data
  infile conti.dat
  replace
  concatenate 2
  into table con_test
  fields terminated by ','
  (a char,   b char,   c char)

  [ 외부 데이타 화일 ]
  1,2,
  3
  a,b,
  c
  A,
  B,C

  [ 검색결과 ]
  SQL> select * from con_test;
  A       B       C
----- ------ -------
  1       2       3
  a       b       c
A       B      C


  6. 포지션 지정시 char형 전후의 블랭크도 로드하고 싶은 경우

   [ 테이블 구조 ]
   create table pretb
   (a varchar(10),    b varchar(10),    c varchar(10))

   [ 콘트롤 화일 ]
   load data
   infile pre.dat
   preserve blanks
   into table pretb
   (a position(01:05) char,
    b position(06:10) char,
    c position(11:20) char)

   [ 외부 데이타 화일 ]
    12 4  67890 ab def hi
       2  67890 ab def hi

   [ 검색결과 ]
   SQL> select * from pretb;
        A       B         C
     ------- ------- ------------
      12 4    67890   ab def hi
         2    67890   ab def hi

   SQL> select length(a), length(c) from pretb;
   LENGTH(A) LENGTH(C)
   --------- ----------
        5        10
5        10


  7. 데이타가 없는 경우 NULL 데이타를 넣고자 할 때

   [ 테이블 구조 ]
   create table tratb
   (a varchar(10),    b varchar(10),    c varchar(10))

   [ 콘트롤 화일 ]
   load data
   infile tra.dat
   into table tratb
   fields termintated by ','
   trailing nullcols
   (a char,
    b char,
    c char)

   [ 외부 데이타 화일 ]
    1,aa,
    2,bb,FF
    3,cc,

   [ 검색결과 ]
   SQL> select * from tratbl
   A       B       C
   ----- ----- -------
     1    aa
     2    bb      FF
     3    cc

  trailing nullcols를 사용하지 않으면 1 레코드째와 3 레코드째가 데이타 에러가 된다.


   8. CHAR형 필드가 BLANK로 채워져 있을 때 NULL을 삽입하고 싶은 경우

   [ 테이블 구조 ]
   create table nulltb
   (a varchar(10),    b varchar(10),    c varchar(10))

   [ 콘트롤 화일 ]
   load data
   infile null.dat
   replace
   into table nulltb
   fields terminated by ','
   (a char,
    b char,
    c char(10) nullif c = blanks)

   [ 외부 데이타 화일 ]
   aa,bb, ,
   11,22, ,
   99,88,AA
   00,00,BB

   [ 검색결과 ]
   SQL> select * from nulltb;
   A       B       C
  ----- ------ ------
  aa      bb
  11      22      
  99      88      AA    
  00      00      BB


9. POSITION 지정시 BLANK를 그대로 로드하고 싶은 경우

   [ 테이블 구조 ]
   create table nulltb2 (a varchar(10),    b varchar(10),    c date)

   [ 콘트롤 화일 ]
   load data
   infile null3.dat
   replace
   preserve blanks
   into table nulltb2
   (a position(1:2) char,
    b position(3:4) char nullif b = blanks,
    c position(5:13) date "YY/MM/DD")

   [ 외부 데이타 화일 ]
   998892/11/11
      94/12/12

   [ 검색결과 ]
   SQL>select * from nulltb2;
    A       B       C
   ----- ----- ---------------
   99      88      92/11/11
                   94/12/12

  SQL> select length(a), length(b) from nulltb2;
  LENGTH(A) LENGTH(B)
  --------- ----------
        2         2
        2


  10. BLANK가 들어가 있을 때 0을 입력하고 싶은 경우

    [ 테이블 구조 ]
    create table def2
    (a varchar(10),     b varchar(10),     c number)

   [ 콘트롤 화일 ]
   load data
   infile def2.dat
   replace
   into table def2
   fields terminated by ','
   (a char,
    b char,
    c integer external defaultif c = blanks)

   [ 외부 데이타 화일 ]
   11,11,123
   22,22, ,
   33,33, ,
   44,44, ,

   [ 검색결과 ]
   SQL> select * from deft;
   A       B        C
  ----- -------- -------
    11      11       123
    22      22         0
    33      33         0
    44      44         0

 

11. 데이타가 NULL일 때 NULL이라고 하는 문자열을 넣을 경우

    [ 테이블 구조 ]
    create table ifnulltb
    (a varchar(10),     b varchar(10),     c varchar(10))

    [ 콘트롤 화일 ]
    load data
    infile ifnull.dat
    replace
    into table ifnulltb
    fields terminated by ','
    (a char,
     b char "nvl(:b,'NULL')",
     c char)

    [ 외부 데이타 화일 ]
    1,2,3,
    A,,B
    a,b,c

    [ 검색결과 ]
    SQL> select * from ifnulltb;
    A       B       C
   ----- ------ --------------
    1       2       3
    A       NULL    B
    a       b       c

   NVL과 같은 SQL 함수는 DIRECT LOAD의 경우 SQL 인터페이스를 경유하지 않기 때문에 사용할 수 없다.


  12. 어떤 열을 모두 대문자(소문자)로 변환하여 로드하는 경우

   [ 테이블 구조 ]
   create table uptb
   (a varchar(10),
    b varchar(10))

   [ 콘트롤 화일 ]
   load data
   infile upper.dat
   replace
   into table uptb
   fields terminated by ','
   (a char "lower(:a)",
    b char "upper(:b)")

   [ 외부 데이타 화일 ]
   aBcDeFg,AbCdEf
   ccDD11,ffGG22

   [ 검색결과 ]
   SQL>select * from uptb;
    A         B      
  ------- -------------
  abcdefg   ABCDEF
  cdd11     FFGG22

'DB' 카테고리의 다른 글

대용량DB에서 FK의 필요성 - sarang.net  (0) 2008.10.28
SQLPlus 사용법  (0) 2008.10.25
토드 단축키  (0) 2008.09.16
데이터 사전정보  (0) 2008.09.15
ORA-01031 권한이 없음  (0) 2008.09.15
Posted by marryjane
|

Heap Dump 생성

java 2008. 9. 18. 10:59

http://blog.naver.com/clotho95/140048453696

1. Sun JDK

 

  1) HPRof 사용

      JDK 버전에 따라 JVM 옵션에 -Xrunhprof:heap=dump,format=b,doe=n (JDK 1.4) 또는 -agentlib:hprof=heap=dump,format=b,doe=n (JDK 1.5)을 명시하고, 실행시에 Control-break 또는 kill -3 <pid> 명령으로 heap dump를 생성할 수 있다. Windows 환경이라면 SendSignal.exe를 사용하면 된다.

      하지만 오버헤드가 너무 커서 운영환경에서 사용하기에는 무리가 따른다. 이 옵션없이 JBoss를 기동하면 30초면 뜨는데, 옵션을 키면 무려 3분 30초가 걸렸다.

 

      * 설정

        - -Xrunhprof:heap=dump,format=b,doe=n (JDK 1.4)

        - -agentlib:hprof=heap=dump,format=b,doe=n (JDK 1.5)

      * heap dump 생성

        - kill -3 <pid>

        - SendSignal.exe <pid>

 

   2) OutOfMemoryError 발생 시 자동으로 heap dump

      JVM 옵션에 -XX:+HeapDumpOnOutOfMemoryError를 설정하면 OutOfMemoryError 발생 시에 heap dump를 현재 실행 디렉터리에 생성한다. JBoss의 경우는 $JBOSS_HOME/bin 디렉터리이다. heap dump가 생성되는 경로를 지정하려면 -XX:HeapDumpPath를 설정해준다.

      Sun JDK 1.4.2_12, 1.5.0_7, 그리고 HP 1.4.2_11 이후 버전에서 지원된다.

 

      * 설정

         - -XX:+HeapDumpOnOutOfMemoryError

         - -XX:HeapDumpPath=/path

       * heap dump 생성

         - OutOfMemoryError 발생시

 

   3) SIGQUIT (kill -3 <pid>)

      JVM 옵션에 -XX:HeapDumpOnCtrlBreak를 설정하면 SIGQUIT signal로 heap dump를 생성할 수 있다. JDK 1.5.0_14 부터 지원된다. 하지만, Windows와 Linux 버전의 JDK 1.5.0_14는 버그로 인해 "/"가 포함된 파일명으로 heap dump를 생성하려고해 No such file or directory라는 에러를 내며 heap dump가 생성되지 않는다. Solaris 버전은 테스트를 못해봤는데 설마 동작하지 않을까 싶다.

 

       * 설정

         - -XX:HeapDumpOnCtrlBreak

       * heap dump 생성

         - kill -3 <pid>

         - SendSignal.exe <pid>

 

   4) jmap 사용

      별도로 JVM 옵션에 명시할 필요없이 JDK에 포함되어 있는 jmap을 사용해 heap dump를 생성할 수 있다. Windows 버전은 JDK 1.5 버전에 jmap이 포함되어 있지 않으므로 사용할 수 없다.

 

       * heap dump 생성

         - jmap -heap:format=b <pid> (JDK 1.5)

         - jmap -dump:format=b,file=<filename> <pid> (JDK 6)

 

2. HP JDK

 

    1)  SIGQUIT (kill -3 <pid>)

        HP의 경우 JVM 옵션에 -XX:+HeapDump를 설정해 SIGQUIT signal로 heap dump를 생성할 수 있다. 기본적으로 text 형식으로 저장되는데 binary 형식이 필요하면 _JAVA_BINARY_HEAPDUMP 환경변수를 설정하면 된다. 이 방법 외에도 Sun JDK처럼 -XX:+HeapDumpOnCtrlBreak를 설정하면 binary heap dump를 생성한다. JVM 옵션을 변경하기 싫으면 _JAVA_HEAPDUMP 환경변수를 설정해도 된다.

       * 설정

         - -XX:+HeapDump 또는 -XX:HeapDumpOnCtrlBreak

         - export _JAVA_HEAPDUMP=1

       * heap dump 생성

        - kill -3 <pid>

 

     2) OutOfMemoryError 발생 시 자동으로 heap dump 생성

        Sun JDK처럼 JVM 옵션에 -XX:+HeapDumpOnOutOfMemoryError를 설정하면 OutOfMemoryError 발생 시에 heap dump를 현재 실행 디렉터리에 생성한다.

 

 

참고자료

http://java.sun.com/javase/6/webnotes/trouble/other/troubleshooting-j2se5.html

http://java.sun.com/javase/6/webnotes/trouble/

http://docs.hp.com/en/5992-1918/ch01s27.html

http://www.latenighthacking.com/projects/2003/sendSignal/

http://forum.java.sun.com/thread.jspa?threadID=681590&messageID=3975318

http://blogs.sun.com/alanb/entry/heap_dumps_are_back_with

Posted by marryjane
|

http://blog.empas.com/flag2ejb/4941495

-Xrunprof 옵션
이 옵션은 단순히 텍스트 형태로 쓰레드 정보와 메소드 호출 점유율, 호출 횟수, 호출 쓰레드 번호등을 보여준다. 이 옵션은 어플리케이션의 성능 측정에서 병목점을 찾을 때 많이 사용한다.
병목점은 찾는 방법은 점유율(%)가 높으면서, 호출 횟수는 작은 순서가 병목점의 순서가 된다.
최근에는 이 옵션은 단순히 HAT(The Heep Analysis Tool)을 실행하기 위한 바이너리 타입의 기초 데이터를 생성(format=b 옵션)하는 용도로 많이 쓰이기도 한다.
 
[craftlee@hurukku testspace]$ java -Xrunhprof:help
Hprof usage: -Xrunhprof[:help]|[:<option>=<value>, ...]
 
Option Name and Value  Description                Default
---------------------  ----------------------     -------
heap=dump|sites|all    heap profiling             all
cpu=samples|times|old  CPU usage                  off
monitor=y|n            monitor contention         n
format=a|b             ascii or binary output     a
file=<file>            write data to file         java.hprof(.txt for ascii)
net=<host>:<port>      send data over a socket    write to file
depth=<size>           stack trace depth          4
cutoff=<value>         output cutoff point        0.0001
lineno=y|n             line number in traces?     y
thread=y|n             thread in traces?          n
doe=y|n                dump on exit?              y
gc_okay=y|n            GC okay during sampling    y
 
Example: java -Xrunhprof:cpu=samples,file=log.txt,depth=3 FooClass
 
Note: format=b cannot be used with cpu=old|times
 
일반적인 사용 옵션
-         java -Xrunhprof <class>
-         java -Xrunhprof:cpu=samples,thread=y <class>
-         java -Xrunhprof:heap=sites <class>
-         java -Xrunhprof:cpu=samples <class>
-         java -Xrunhprof:cpu=samples,file=log.txt <class>
-         java -Xrunhprof:cpu=samples,format=b <class>
 
실행 예) 위에서 만든 “wileUnit.class”을 이용한다.
 
1.       java -Xrunhprof:cpu=samples,thread=y whileUnit 옵션으로 실행
THREAD START (obj=811a410, id = 1, name="Finalizer", group="system")
THREAD START (obj=811a530, id = 2, name="Reference Handler", group="system")
THREAD START (obj=811a5f8, id = 3, name="main", group="main")
THREAD START (obj=813c9c8, id = 4, name="Signal Dispatcher", group="system")
THREAD START (obj=813ca58, id = 5, name="HPROF CPU profiler", group="system")
THREAD END (id = 3)
THREAD START (obj=814daf8, id = 6, name="DestroyJavaVM", group="main")
THREAD END (id = 6)
TRACE 1: (thread=3)
        <empty>
TRACE 2: (thread=3)
        whileUnit.exec(whileUnit.java:15)
        whileUnit.main(whileUnit.java:27)
CPU SAMPLES BEGIN (total = 2) Mon Nov 22 12:59:32 2004
rank   self  accum   count trace method
   1 100.00% 100.00%       2     2 whileUnit.exec
CPU SAMPLES END
2.       위에서는 실행 메소드가 하나 뿐이 없어서 100%을 차지 하고있다.
3.       java -Xrunhprof:heap=sites whileUnit 옵션으로 실행
 
percent         live       alloc'ed  stack class
 rank   self  accum    bytes objs   bytes objs trace name
    1 63.90% 63.90%   602072  234  602072  234     1 [I
    2 16.32% 80.23%   153800  577  153800  577     1 [C
    3  5.02% 85.25%    47280  230   47280  230     1 [B
….
메모리에 점유율이 높은 객체 Ranking이 출력된다. 여기서 [I, [C, [B 타입은 Integer, Character, Byte 배열이다.
Posted by marryjane
|

http://ukja.tistory.com/tag/Java.OutOfMemoryError

사내에서 하는 프로젝트의 일환으로 Java의 성능 이슈에 대한 다양한 컨텐츠를 작성 중인데... 그 중 유용하다고 생각되는 내용 일부를 블로그를 통해서 공개할 생각이다. 그 첫번째 내용으로 악명높은 Out Of Memory Error, 흔히 OOM(E)라고 부르는 현상의 원인과 해결책에 대해 정리한 문서를 소개한다...


OOME 개요

JVM이 일정한 크기의 메모리를 할당하는데 실패하면 Out Of Memory Error, 이른바 OOME가 발생한다.

OOME의 발생 원인은 매우 다양하며, 이는 JVM이 사용하는 메모리 공간의 다양성에 기인한다. 대부분의 JVM은그 사용 용도에 따라 메모리를 몇가지 종류로 구분해서 사용한다. 가령 Sun HotSpot JVM은 다음과 같은 세 가지 종류의메모리 공간을 사용한다.((참고) 통상적으로 Permanent Space는 Java Heap의 하위 영역으로 설명된다. 하지만 본 문서에서는 Java Heap = Young Generation + Old Generation으로 간주한다)

  1. Java Heap: 사용자가 생성하는 Java Object들이 거주하는 공간이다. -Xms와 -Xmx Option에 의해 크기가 결정된다.
  2. Permanent Space: Class에 대한 메타 정보를 저장하는 공간이다. -XX:PermSize=와 -XX:MaxPermSize= Option에 의해 크기가 결정된다.
  3. Native Heap: Java Object가 아닌 Native Object들이 거주하는 공간이다. Native Heap의 크기는 JVM Option으로 지정할 수 없으며, OS 차원에서 결정된다.


각 메모리 공간의 용도와 사용 방식이 틀리기 때문에 OOME또한 매우 다양한 상황에서 발생하게 된다. OOME가 발생하는 정확한 원인을 분석하려면 각 메모리 공간의 특성을 이해하고 그에 맞는 해결책을 모색해야 한다.

(주의) 비록 Java 언어와 JVM이 자동화된 메모리 관리 기능을 제공하지만, 이것이개발자나 관리자가 메모리 관리에 대해 무신경해도 된다는 것을 의미하지 않는다는 사실을 명심하자. Java에서도 잘못된 메모리관리는 여전히 많은 문제를 일으키며, Garbage Collection에 의한 성능저하나 OOME에 의한 Applictaion정지나 System Crash등이 대표적인 예이다.

Java Heap에서의 OOME

Java Heap에서 OOME가 발생하는 경우에는 다음과 같은 에러 메시지가 출력된다.

Exception in thread "main": java.lang.OutOfMemoryError: Java heap space 또는
Exception in thread main: java.lang.OutOfMemoryError: Requested array size exceeds VM limit

전자의 메시지는 Java Heap Space의 부족으로 Object를 생성하지 못하는 경우에 발생한다. 후자의메시지는 Java Heap의 최대 크기보다 큰 Array가 요청되는 경우에 발생한다. 가령 Java Heap의 최대 크기가256M인 상황에서 300M 크기의 Array를 생성하는 경우가 이에 해당한다.

Java Heap에서 OOME가 발생하는 이유는 다음과 같다.

  • Java Heap의 크기가 작은 경우
  • Memory Leak이 발생하는 경우
    • Application Logic에 의한 Memory Leak
    • JDK Bug나 WAS Bug에 의한 Memory Leak
  • finalize 메소드에 의한 Collection 지연


Java Heap의 크기와 OOME

Java Heap의 최대 크기가 Application의 메모리 요구량에 비해 작게 설정된 경우에 OOME가 발생한다.Memory Leak이 발생하지 않는데도 OOME가 발생한다면 Java Heap의 크기가 부족하다고 판단할 수 있다.-Xmx 옵션을 이용해서 Java Heap의 최대 크기를 키워주어야 한다.

Memory Leak과 OOME

Memory Leak이발생하는 경우에는 Java Heap의 크기와 무관하게 OOME가 발생할 수 있다. 아무리 Java Heap의 크기를 크게하더라도 결국 Memory Leak에 의해 Collection되지 않는 Garbage 객체들이 메모리를 다 소진하기 때문이다.Memory Leak은 대부분 잘못된 Application 로직에 의해 발생한다. Object에 대한 참조(Reference)관계가 복잡한 경우 조그마한 실수로 인해 사용되지 않은 Object를 계속해서 참조하게 된다. 이러한 Object들은 비록Application에서는 사용되지 않지만 Garbage Collection에 의해 메모리 해제가 이루어지지 않기 때문에OOME를 유발하게 된다.

JDK Bug나 WAS Bug에 의해서도 Memory Leak이 발생할 수 있다. JDK가 제공하는 라이브러리나WAS가 제공하는 라이브러리에서 로직 오류로 인한 Memory Leak 가능성이 있기 때문이다. ApplicationLogic에서 Memory Leak이 검출되지 않는 경우에는 JDK나 WAS의 Bug를 의심해볼 필요가 있으며 각 Vendor가제공하는 Bug Database를 통해 검색 가능하다.

finalize 메소드에 의한 Collection 지연과 OOME

특정 Class에 finalize 메소드가 정의되어 있는 경우, 이 Class Type의 Object는 GarbageCollection 발생시 즉각적으로 Collection 되지 않는다. 대신 Finalization Queue에 들어간 후Finalizer에 의해 정리가 된다. Finalizer는 Object의 finalize 메소드를 실행한 후 메모리 정리 작업을수행한다. 만일 finalize 메소드를 수행하는데 오랜 시간이 걸린다면 그 만큼 객체가 오랫동안 메모리를 점유하게 된다. 이로인해 OOME가 발생할 확률이 높아진다. 이런 이유 때문에 finalize 메소드는 되도록 사용하지 말아야 한다.

Object Allocation Profiling

Java Heap의 메모리 부족 문제를 정확하게 분석하려면 Object Allocation Profiling을 수행해야한다. 즉, 어떤 Object가 어느 개수만큼 생성되었으며 얼마나 많은 메모리를 차지하는지 분석할 필요가 있다. HProf는 모든 JVM이 표준으로 제공하는 Profiler로, 간단한 Object Allocation Profiling 기능을 제공한다.

 java -Xrunhprof:heap=sites [Main Class] 

또는 다음과 같이 doe(dump on exit) Option을 비활성화해서 시간순으로 Profiling을 수행할 수도 있다.

 java -Xrunhprof:heap=sites,doe=n [Main Class]
...
Control+Break (혹은 다른 Console에서 kill -3 [pid])

Java Process에서 Signal을 보내서 Dump를 생성하는 방법은 Thread Dump를 참조한다.

아래에 HProf를 이용한 Object Allocation Profiling 결과의 간단한 Sample이 있다. 아래 Sample에서는 byte[] 유형의 객체가 20%의 Heap 공간을 사용하는 것을 알 수 있다.

        percent          live          alloc'ed  stack class
rank self accum bytes objs bytes objs trace name
1 20.36% 20.36% 190060 16 190060 16 300000 byte[]
2 14.92% 35.28% 139260 1059 139260 1059 300000 char[]
3 5.27% 40.56% 49192 15 49192 15 300055 byte[]
4 5.26% 45.82% 49112 14 49112 14 300066 byte[]
5 4.32% 50.14% 40308 1226 40308 1226 300000 java.lang.String
6 1.62% 51.75% 15092 438 15092 438 300000 java.util.HashMap$Entry
7 0.79% 52.55% 7392 14 7392 14 300065 byte[]
8 0.47% 53.01% 4360 16 4360 16 300016 char[]
9 0.47% 53.48% 4352 34 4352 34 300032 char[]
10 0.43% 53.90% 3968 32 3968 32 300028 char[]
11 0.40% 54.30% 3716 8 3716 8 300000 java.util.HashMap$Entry[]
12 0.40% 54.70% 3708 11 3708 11 300000 int[]

Permanent Space에서의 OOME

Permanent Space에서 OOME가 발생하면 다음과 같은 에러 메시지가 출력된다

Exception in thread "main": java.lang.OutOfMemoryError: Perm Gen space'

Permanent Space는 Class의 메타 정보를 저장하는 공간이다. 따라서 많은 수의 Class를 로딩하는Application의 경우 Permanent Space의 크기가 작으면 OOME가 발생할 수 있다. 다음과 같은 유형의Application들에서는 Permanent Space의 크기를 키워줄 필요가 있다.

  • 매우 많은 수의 JSP 파일을 로딩하는 Web Application. JSP 파일은 Servlet으로 변환된다.하나의 Servlet은 하나의 Java Class에 해당한다. 따라서 이 경우 매우 많은 수의 Class가 로딩된다.
  • ReflectionMechanism을 사용해 동적으로 Class를 로딩하는 Framework. Spring과 같은 현대적인 Framework들은Reflection Meachanism을 통해 동적으로 Class를 생성한다. 이 경우 개발자가 의도하지 않은 많은 수의Class들이 로딩될 수 있다.

이런 문제는 대부분의 Permanent Space의 크기를 키워주면 해결된다.-XX:PermSize=, -XX:MaxPermSize= Option을 이용해Permanent Space의 최소 크기와 최대 크기를 지정할 수 있다.

Class Loading 모니터링

Permanent Space에 Loading되는 Class의 목록을 모니터링함으로써 OOME가 발생하는 원인을 간접적으로 분석할 수 있다. 다음과 같은 방법을 통해 Class Loading을 모니터링할 수 있다.

  • -verbose:gc: Loading되는 Class들을 Standard Out을 통해 출력해준다.
  • Platform MBean: JMX 표준을 통해 제공되는 ClassLoadingMXBean API를 이용하면 프로그래밍적으로 Class Loading 정보를 얻을 수 있다.
  • JConsole: JConsole을 이용하면 Class Loading 정보를 조회할 수 있다. JConsole은 JMX 클라이언트의 표준 샘플로 Platform MBean과 통신해서 Class Loading 정보를 얻는다.

아래에 -verbose:class 옵션에 의한 Class Loading 모니터링의 간단한 Sample이 있다. Open된 jar 파일과 Loading된 Class 목록을 확인할 수 있다.

[Opened c:bea10jdk150_06jrelibrt.jar]
[Opened c:bea10jdk150_06jrelibjsse.jar]
[Opened c:bea10jdk150_06jrelibjce.jar]
[Opened c:bea10jdk150_06jrelibcharsets.jar]
[Loaded java.lang.Object from c:bea10jdk150_06jrelibrt.jar]
[Loaded java.io.Serializable from c:bea10jdk150_06jrelibrt.jar]
[Loaded java.lang.Comparable from c:bea10jdk150_06jrelibrt.jar]
[Loaded java.lang.CharSequence from c:bea10jdk150_06jrelibrt.jar]
[Loaded java.lang.String from c:bea10jdk150_06jrelibrt.jar]
[Loaded java.lang.reflect.GenericDeclaration from c:bea10jdk150_06jrelibrt.jar]
...

(참조) IBM JVM에서는 Thread Dump에서도 Class Loading 정보를 제공한다.

Class Reloading과 OOME

현대적인 대부분의 WAS가 Class Reloading 기능을 제공한다. Class Reloading이란 Runtime에Class가 재생성되면 이를 JVM을 Reboot하지 않고 Reloading하는 기능을 의미한다. 일부 WAS의 경우Class가 Reloading될 때 이전 버전의 Class를 해제하지 않는 경우가 있다. 따라서 Class Reloading이자주 발생하면 Permanent Space가 금방 꽉차게 되고 OOME가 발생하게 된다. 이와 같은 경우에는 WAS가 제공하는버그 패치를 적용하거나 WAS를 주기적으로 Restart해야 한다.

Native Heap에서의 OOME

Java Heap과 Permanent Space가 Java와 관련된 Object들이 거주하는 공간인 반면, NativeHeap은 OS 레벨의 Native Object나 JNI Library 레벨의 Native Object이 거주하는 공간이다.

Native Heap에서 OOME가 발생하면 다음과 같은 에러 메시지가 출력된다.

java.lang.OutOfMemoryError: request bytes for . Out of swap space? 또는
java.lang.OutOfMemoryError: (Native method)' 또는
java.lang.OutOfMemoryError: unable to create new native thread


첫번째 메시지는 VM code 레벨에서 메모리 부족 현상이 발견된 경우이다. 두번째 메시지는 JNI나 Native Method에서 메모리 부족 현상이 발견된 경우에 해당한다. 세번째 메시지는 Thread를 생성할 수 없을 때 발생한다. Thread는Native Heap 공간의 메모리를 필요로 하기 때문에 Native Heap 공간의 메모리가 부족하면 Thread 생성시OOME가 발생한다.

Native Heap에서 메모리 부족이 발생하는 이유는 매우 다양하다.

  • Thread Stack Space가 부족한 경우
  • Virtual Space Address가 소진된 경우
  • Swap Space가 모자란 경우
  • JNI Library에서 Memory Leak이 발생하는 경우

Thread Stack Space와 OOME

Java Thread는 Native Heap 공간에 Stack Trace를 저장할 공간을 필요로 한다. ThreadStack Space의 크기는 -Xss 옵션을 통해 지정된다. -Xss 옵션을 통해지정되는 공간은 개별 Thread가 사용하는 공간이다. 만일 N개의 Thread가 활성화되면 N* 만큼의메모리 공간이 필요하다.

대부분의 OS에서 Thread Stack Size는 512K ~ 1M 사이다. 따라서 많은 수의 Thread가 활성화되면 Thread Stack Space만으로도 큰 크기의 Native Heap 메모리 공간을 소모한다.

Thread Stack Space 문제에 의한 OOME를 해소하는 방법은 다음과 같다.

  • Thread의 수를 줄인다. 동시에 수십개 이상의 Thread를 사용하는 것은 메모리의 문제 뿐만 아니라 지나친 Context Switching으로 인해 성능을 저하시키는 요인이 된다. Thread Pool 기법을 사용해서 동시 Thread의 수를 줄인다. 대부분의 WAS들이 Thread Pool 기법을 사용하고 있다.
  • Thread Stack Size를 줄인다. 대부분의 OS에서 Thread Stack Size는512K ~ 1M이다. 만일 많은 수의 Thread가 필요한 Application이라면 Thread Stack Size를줄임으로써 OOME를 방지할 수 있다. 많은 경우 -Xss128k 정도나 -Xss256k 정도의 크기에서도 문제없이 작동한다.단, Stack Size가 줄어든 만큼 Stack Overflow Error가 발생할 확률은 높아진다.
  • Java Heap 크기를 줄인다. 32bit Process가 사용 가능한 메모리 공간은 OS에따라 2G ~ 4G로 제한된다. 하나의 Java Process가 사용 가능한 공간은 [Java Heap+PermanentSpace+Native Heap]으로 이루어진다. 따라서 Java Heap이 지나치게 큰 공간을 사용하는 경우 NativeHeap에서 사용 가능한 공간이 줄어들게 된다. 따라서 Java Heap 크기를 줄이면 Native Heap의 메모리 부족에의한 OOME 문제를 해결 할 수 있다. 하지마 Java Heap 크기를 지나치게 줄이면 Java Heap 부족에 의한 OOME현상이 발생할 수 있으므로 유의해야 한다. Java Heap 크기를 줄이는 방법은 Thread Stack Space의 부족 문제뿐 아니라 Native Heap 부족에 의한 OOME 문제를 줄이는 공통적인 해결 방법이다.
  • 64bit JVM을 사용한다. 64bit JVM에서는 32bit JVM Process가 가지는2G ~ 4G의 제한이 없다. 따라서 Native Heap의 메모리 부족 문제가 줄어든다. 이 방법 또한 Native heap부족에 의한 OOME 문제를 줄이는 공통적인 해결 방안이다.

64bit JVM을 사용하는 경우, 다음과 같은 사실에 유의해야 한다.

  1. 일반적으로 32bit Application의 성능이 64bit Application에 비해 더 나은 성능을보이는 경우가 많다. 따라서 64bit JVM을 사용하는 경우 약간의 성능 저하가 발생할 수 있다는 사실에 유의해야 한다.
  2. 과도한 Virutal Memory의 사용은 Application의 성능을 저하시키는 주요인이다. JavaApplication의 성능은 모든 Object들이 Physical Memory에 머물러 있을때 가장 뛰어나다. 만일Physical Memory를 초과하는 크기의 Virtual Memory를 사용하면 Physical Memory의 일부를Disk에 저장하는 Paging In/Out이 발생한다. Paging In/Out은 Memory Operation에 비해 매우느리며 그만큼 Application의 성능도 저하된다.


Virtual Address Space와 OOME

32bit JVM에서 사용가능한 Virtual Address Space의 최대 크기는 OS에 따라 2G ~ 4G로제한된다. Java Process의 경우 Java Heap과 Permanent Space를 제외한 나머지 공간만을 NativeHeap이 사용할 수 있다. 가령 2G의 Virtual Address Space만이 사용가능하다고 가정하자. 이 때 JavaHeap이 1G, Permanent Space가 200M를 사용한다면 Native Heap이 사용 가능한 최대 크기는 800M에불과하다. 800M 중에는 OS가 Process 관리를 위해 사용하는 기본 메모리가 포함되기 때문에 실제로 JavaApplication이 사용 가능한 Native Heap의 크기는 훨씬 줄어든다. 따라서 이 경우 Native Heap 공간부족에 의한 OOME가 발생할 확률이 높아진다.

Virtual Address Space 부족에 의한 OOME를 해결하는 방법은 Thread Stack Space에의한 OOME 해결방안과 일맥상통한다. Java Heap 크기를 줄이거나 64bit JVM를 사용한다. Thread 수를줄이거나 Thread Stack Size를 줄임으로써 Native Heap 공간을 확보하는 것도 방법이 될 수 있다.

Swap Sapce와 OOME

Physical Memory를 초과하는 Virtual Memory 요청이 발생하면 Paging In/Out을 통해 필요한 메모리를 확보한다. Paging In/Out을 위한 공간이 Swap 공간이다. 따라서 Swap Space가 부족하면 Paging In/Out에 실패하고 이로 인해 OOME가 발생한다.

여러 개의 Process가 Swap Space를 사용하는 경우 Swap Space 부족에 의한 OOME가 발생할확률이 높아진다. OS가 제공하는 툴들을 통해 Swap Space와 Paging In/Out을 모니터링해야 하며, SwapSpace가 부족한 경우에는 크기를 키워주어야 한다.

OOME와 Fatal Error Log

Native Heap에서 OOME가 발생하면 JVM은 심각한 상황이라고 판단하고 Fatal Error Log를 남긴다. 아래에 OOME가 발생한 상황에서의 Fatal Error Log의 Header 정보에 대한 간단한 Sample이 있다.

#
# An unexpected error has been detected by Java Runtime Environment:
#
# java.lang.OutOfMemoryError: requested 20971520 bytes for GrET in C:BUILD_AREA
jdk6_02hotspotsrcsharevmutilitiesgrowableArray.cpp. Out of swap space?
#
# Internal Error (414C4C4F434154494F4E0E494E4C494E450E4850500017), pid=5840, ti
d=5540
#
# Java VM: Java HotSpot(TM) Client VM (1.6.0_02-b06 mixed mode)
# An error report file with more information is saved as hs_err_pid5840.log
#
# If you would like to submit a bug report, please visit:
# http://java.sun.com/webapps/bugreport/crash.jsp
#

Fatal Error Log를 통해 OOME를 유발한 Thread와 Stack Trace를 추적할 수 있다. 이 정보가 곧 해결책을 의미하지는 않지만, 추가적인 분석을 위한 힌트가 될 수 있다.

Posted by marryjane
|

http://www.javaservice.net/~java/bbs/read.cgi?m=etc&b=jdk&c=r_p&n=1117521098&p=1&s=t#1117521098

java.lang.OutOfMemoryError

 

                     2005-05-31     송학렬    ㈜아이티플러스 기술지원부

 

 

이 문서는 기술지원 또는 개발 시 java.lang.OutOfMemoryError 를 만났을 때 원인 파악 및 해결방안 입니다.

 

 

java.lang.OutOfMemoryError 에는 크게 2가지 패턴이 있다고 볼 수 있습니다.(전적으로 개인적인 생각이지만..^^)

Java의 heap 메모리가 정말로 Full 되서 나는 종류가 있고 그렇지 않은데도 나는 종류가 있습니다.

그 둘 중에 어는 것 인지부터 가려내는 것이 가장 먼저 선행되어야 합니다.

Java 가상머신에는 메모리 구조가 여러단계로 나뉘어 져 있으므로 어느 영역에 의해 java.lang.OutOfMemoryError 가 나는지 알기 위해 JAVA OPTION으로 싸이트가 안정화 되기 전까진 verbosegc 또는 -XX:+PrintGCDetails  옵션을 추가해 놓는 것이 java.lang.OutOfMemoryError 났을 때를 대비해 좋은 습관이라 할 수 있습니다.

 

-verbosegc 또는  -XX:+PrintGCDetails  옵션으로 로그에 남는 heap 메모리 정보를 본 후 java.lang.OutOfMemoryError 가 날 때 heap이 꽉 차서 나는 것인지 아닌지 부터 판단합니다.

 

1.     Heap Memory가 Full 차지 않았을 때

1)     Perm 영역이 full 되는 경우

 

Permanent generation is full...

increase MaxPermSize (current capacity is set to: 134217728 bytes)

 

[Full GC[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor31282]

 810207K->802132K(1013632K), 8.3480617 secs]

<GC: 2 4  2465625.831280 10348 0 31 113802808 105534632 286326784 0 0 35782656 715849728 715848840 715849728 134217720 134023296 134217728 8.348677 8.348677 >

Passwd Check =============

<2005. 5. 19. 오전 9시 32분 23초 KST> <Error> <HTTP> <BEA-101017> <[ServletContext(id=2536415,name=/,context-path=)] Root cause of ServletException.

java.lang.OutOfMemoryError

위와 같은 case 인 경우네는 Java 가상머신중에 Perm 영역이 full 차는 경우 입니다. 

Perm 영역에는 class object 및 관련된 meta data가 로드되는 곳인데 싸이트가 매우 많은 수의 class를 사용하는 경우 늘려줘야 하는 case도 있습니다.

얼마가 적정한 사이즈란 정답이 없는 것 같고 max가 계속 늘어나지 않고 일정한 사이즈를 유지 하면 됩니다.

 

             위 에러가 났을때는 -XX:MaxPermSize=256m  옵션으로 사이즈를 적당하게 늘려주는게 방

             법이며 늘려주었는데도 불구하고 Full 차는 시간만 늘어날 뿐 계속 사이즈가 늘어난다면 이 영역은 일반 비즈니스 프로그램으로 핸들링 할 수 없는 영역이므로 WAS 제품의 버그 및 jdk 버그로 보는 것이 일반적입니다.

       

2)     MAXDSIZ 사이즈 관련

  - Exception in thread "CompileThread0" java.lang.OutOfMemoryError: requested 32756 bytes for ChunkPool::allocate

Possible causes:

         - not enough swap space left, or

         - kernel parameter MAXDSIZ is very small.

-          java.lang.OutOfMemoryError: unable to create new native thread

 

위 두 에러가 나는 이유는 Data 사이즈가 Full 차서 더 이상 메모리 할당을 할 수 없다는 java.lang.OutOfMemoryError 입니다.

 

Jdk도 내부적으로 c 라이브러리를 쓰고 jni를 통해서 c프로그램을 호출할 수 도 있는 환경에서 Data 영역이상으로 메모리 사용 시 위 에러를 만날 수 있습니다.

Heap 영역에는 java heap과 C heap이 있는데 C heap이 Data 메모리 영역에 영향을 미치는 것으로 보이며 보통 C의 전역 변수들이 잡히는 영역입니다.

 

위 현상을 만났을 때는 hp os의 MAXDSIZ가 너무 작게 잡혀있지 않은지 확인 후 적당한 크기로 늘려 줘야 합니다.

 

Glance 에서 shift+m 을 누른 후 jvm pid를 누르면 java가 사용하는 Data 사이즈를 모니터링 할 수 있습니다.

모니터링을 통해 적정한 사이즈로 MAXDSIZ를 늘려주어야 하며 만일 늘려 준게 에러 발생의 시간만 지연 시킬 뿐 계속 사용량이 늘어난다면 이는 사용하는 c라이브러리 쪽에 메모리 릭 버그가 있는 것이므로 c라이브러리를 체크 하셔야 합니다.

java.lang.OutOfMemoryError: unable to create new native thread

이 경우는 프로그램에서 Thread pool 프로그램 실수로 필요이상으로 쓰레드가 생성되는 경우도 과도하게 메모리를 사용할 수 있으므로 jvm 쓰레드 덤프를 통해 과도한 쓰레드가 생성되지 않았는지도 확인해 보셔야 합니다.

 

2.     Heap이 Full 찾을 때

이 경우는 java가 사용하는 heap 영역이 Full 되서 java.lang.OutOfMemoryError 가 나는 경우 인데 두 가지 패턴이 있습니다.

순간적으로 대량의 데이터를 메모리에 올리는 프로그램이 실행되어 문제를 야기 할수 있으며 다른 한 가지는 조금씩 메모리 릭이 발생하여 점차적으로 메모리가 쌓여 가는 경우 입니다.

두 가지 중에  어느 것인지 구별하는 것이 중요하며 이를 위해서도 마찬가지로 -verbosegc 또는  -XX:+PrintGCDetails  로그를 통해 순간적으로 메모리가 차는 것인지 조금씩 메모리가 차는 것인지를 확인하셔야 합니다.

 

1) 특정 프로그램의 특정시점의 과도한 메모리 사용에 의한 경우

                특정 프로그램이 과도하게 heap 메모리 이상 메모리를 사용하면서

java.lang.OutOfMemoryError가 발생하는 경우는 이 에러가 발생하는 시점의 쓰레드 덤프를 통해 어느 프로그램인지 쉽게 찾을 수 있습니다.

쓰레드 덤프에 메모리를 쓸만한 프로그램은 어느 정도의 자바프로그램 경험이 있으면 찾을 수 있습니다.

 

Ex)

"ExecuteThread: '36' for queue: 'default'" daemon prio=10 tid=0x0048e7b0 nid=48 lwp_id=4139729 runnable [0x23f32000..0x23f30500]

          at java.net.SocketInputStream.socketRead(Native Method)

          at java.net.SocketInputStream.read(Unknown Source)

          at oracle.net.ns.Packet.receive(Unknown Source)

          at oracle.net.ns.NetInputStream.getNextPacket(Unknown Source)

          at oracle.net.ns.NetInputStream.read(Unknown Source)

          at oracle.net.ns.NetInputStream.read(Unknown Source)

          at oracle.net.ns.NetInputStream.read(Unknown Source)

          at oracle.jdbc.ttc7.MAREngine.unmarshalUB1(MAREngine.java:718)

          at oracle.jdbc.ttc7.MAREngine.unmarshalSB1(MAREngine.java:690)

          at oracle.jdbc.ttc7.Oall7.receive(Oall7.java:373)

          at oracle.jdbc.ttc7.TTC7Protocol.doOall7(TTC7Protocol.java:1405)

          at oracle.jdbc.ttc7.TTC7Protocol.fetch(TTC7Protocol.java:889)

          - locked <0x35e8e3b0> (a oracle.jdbc.ttc7.TTC7Protocol)

          at oracle.jdbc.driver.OracleResultSetImpl.next(OracleResultSetImpl.java:242)

          - locked <0x36f66c98> (a oracle.jdbc.driver.OracleResultSetImpl)

          at weblogic.jdbc.pool.ResultSet.next(ResultSet.java:180)

          at Dcard.AAA.ejb.monitor.member.wbbb.WACBean.getInfoList(WACBean.java:5789)

 

java.lang.OutOfMemoryError 가 날 상황에 쓰레드 덤프를 두 세번 떠서 같은 쓰레드 번호로 위 같은 로직이 오래 결려있다면 이는 프로그램에서 while(rs.next()) 를 오랜 기간 돌면서 메모리에 DB로부터 읽어서 올리고 있다는 것을 의미 합니다 대량 데이터 조회가 일어나는 경우인 것 입니다.

 

이런 식으로 특정 프로그램의 특정 시점에 과도한 메모리 사용으로 인한 java.lang.OutOfMemoryError 에러는 쓰레드 덤프를 통해 찾을 수 있습니다.

-- 물론 2번에서 설명 할 heap dump를 통해서도 찾을 수 있습니다.

 

2) 메모리 릭에 의해 조금씩 메모리가 쌓인 경우

JVM위 에서 실행중인 프로그램중에 어떤 것이 GC 대상에서 제외되는 영역에 data를 조금씩 쌓고 있다는 얘기입니다.

GC 대상에서 제외되는 영역은 다음과 같은 곳이 있습니다.

- Http Session에 넣는 데이터..(세션 타임아웃 또는 invilidate 씨 까지 제외됨)

- Static 변수

- 서블릿 또는 jsp의 멤버변수 ( WAS 기동 후 최초 호출 시 인스턴스 화 되어 WAS가 내려 갈 때 까지 사라지지 않음 )

- EJB의 멤버변수( pool안에서 객체가 존재하는 한 GC대상에서 제외)

          위 같은 영역에 프로그램에서 data를 add 하는 구조를 메모리 릭 이라고 할 수 있습니다.

           IBM 또는 SUN JDK 인 경우에는 heapdump를 통해서 분석하여 어느 데이터가 메모리를 많이 잡고 있는지를 알 수 있습니다.

           Heapdump 사용법 및 분석 법은 다음을 참조 하시면 됩니다.

 http://www.alphaworks.ibm.com/aw.nsf/FAQs/heaproots

http://www-1.ibm.com/support/docview.wss?uid=swg21190476

http://www-1.ibm.com/support/docview.wss?rs=180&context=SSEQTP&q1=heapdump+solaris&uid=swg21190608&loc=en_US&cs=utf-8&lang=en

http://www.skywayradio.com/tech/WAS51/IBMHeapDump/

 

Posted by marryjane
|

http://okjsp.pe.kr/seq/122183

jxl은 대용량데이터를 엑셀문서를 통해 입력할때 속도가 빠릅니다.
단점은 엑셀형식으로 데이터를 받았을때 제대로 된 엑셀이 아니라 조작이 좀 그렇습니다.
반대로 poi는 데이터를 엑셀문서로 다운받았을때 제대로 된 엑셀문서라 현업들이 바로 조작하고 사용하기가 편합니다.
하지만 데이터를 넣을때 소량은 상관없지만 수만개이상넣을때..좀 느립니다.
그래서 저도 지금까지 4,5번해봤지만 데이터를 넣을때는 jxl로 데이터를 받을때는 poi로 합니다.
Posted by marryjane
|

http://kin.naver.com/detail/detail.php?d1id=1&dir_id=10102&eid=X3/YQCPY9/+a9yR4FpqEJlYn4mNSb0LE&qb=anhsIMDMuczB9g==&pid=fK8I1soi5Uhssb7go4ssss--154326&sid=SM85U5giz0gAAFizEvo

테스트는 안해봤음.

import java.awt.Graphics;
import java.awt.image.ImageObserver;
import java.awt.image.ImageProducer;
import jxl.*;
import java.io.*;
import java.sql.*;

public class Test3 {
    //frame의 내부무명클래스의 메서드에서 사용할수 있게 전역변수로 설정함
    javax.swing.ImageIcon icon = null;    


    public void excel2(){
        try{
            Workbook workbook = null;
            Sheet sheet = null;
           
            workbook = Workbook.getWorkbook(new File("excel/test.xls"));//엑셀파일 위치입니다.
           
            sheet = workbook.getSheet(0);
           
            //이미지 갯수를 카운트합니다
            for(int i=0;i<sheet.getNumberOfImages();i++) {
                //가지고 오는 이미지의 사이즈 체크
                if(sheet.getDrawing(i).getImageData().length>0) {
                    //이미지 파일을 생성하고 for문 종료합니다.
                    icon = new javax.swing.ImageIcon(sheet.getDrawing(i).getImageData());
                    break;
                }
            }
           
            javax.swing.JFrame frame = new javax.swing.JFrame(){
                //paint메소드 상속하여 구현해줌....icon은 Test3 클래스의 icon입니다.
                public void paint(java.awt.Graphics g) {
                    g.drawImage(icon.getImage(), 0, 0, this);
                }

            };
           
            frame.setSize(500, 500);
           
            frame.setDefaultCloseOperation(javax.swing.JFrame.DISPOSE_ON_CLOSE);
           
            frame.setVisible(true);


        }catch(Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        new Test3().excel2();
    }
}

Posted by marryjane
|

토드 단축키

DB 2008. 9. 16. 11:08

http://dongchimi.unfix.net/2008/07/-by.html

테이블 정보 상세보기
F4 : Table, View, Proc, Funct, Package를 DESC(테이블명 위에 커서를 두고 F4키)
 
자동완성
Ctrl+. : Table Completion (매칭되는 테이블목록 출력)
Ctrl+T : Columns Dropdown (해당테이블의 컬럼목록 표시)
 
SQL문 실행
F5 : SQL Editor내의 모든 SQL문 실행
Ctrl+Enter : 현재 커서의 SQL문 실행
F9 : SQL문 실행 후 Grid에 출력
 
히스토리(과거 수행SQL문 조회)
F8 : 과거에 실행한SQL문 HISTORY 목록
Alt+Up : History UP
Alt+Down : History DOWN
 
텍스트 대/소문자 변환
CTRL+L : 텍스트를 소문자로
CTRL+U : 텍스트를 대문자로
 
주석처리
Ctrl+B : 주석처리
Ctrl+Shift+B : 주석해제
 
편집 창 전환(이동)
F6 : SQL Editor와 결과창간의 이동
F2 : SQL Editor창 전체화면 전환
Shift+F2 : Grid Output창 전체화면 전환
 
기타 단축키
F7 : 화면을 모두 CLEAR
Ctrl+Shift+F : 쿼리문을 보기좋게 정렬
Ctrl+F9 : SQL문 Validate (SQL문을 수행하지 않음)

'DB' 카테고리의 다른 글

SQLPlus 사용법  (0) 2008.10.25
SQL loader 사용하기  (0) 2008.09.19
데이터 사전정보  (0) 2008.09.15
ORA-01031 권한이 없음  (0) 2008.09.15
ORA-27121 unable to determine size of  (0) 2008.09.15
Posted by marryjane
|

데이터 사전정보

DB 2008. 9. 15. 19:50

◈ 아래 데이터사전 정보는 인터넷 정보를 참고했습니다.

* 오브젝트: USER_OBJECTS(OBJ)
   모든 오브젝트에 대한 정보를 지원
   오즈젝트 유형, 작성시간, 오브젝트에 사용된 최종 DDL 명령, alter, grant 및 revoke 등


* 테이블 : USER_TABLES (TABS)   테이블에 대한 정보


* 열 : USER_TAB_COLUMNS (COLS)   컬럼에 대한 정보


* 뷰 : USER_VIEWS   뷰에 대한 정보


* 동의어 : USER_SYNONYMS (SYN)


* 시퀀스 : USER_SEQUENCES (SEQ)


* 제약조건 : USER_CONSTARINTS


* 제약조건열 :  USER_CONS_COLUMNS ( 제약 조건을 가진 열에 대한 정보)


* 제약조건의 예외사항 : EXCEPTIONS  제약조건을 활성화시 에러사항에 대한 정보


* 테이블 주석 : USER_TAB_COMMENTS  테이블/뷰에 대한 주석


* 열 주석 : USER_COL_COMMENTS ( 열에 대한 주석)


* 인덱스 : USER_INDEXES (IND) ( 인덱스에 관한 정보)


* 인덱스 열 : USER_IND_COLUMNS  인덱스열에 대한 정보


* 클러스터 : USER_CLUSTERS (CLU)  클러스터와 관련된 정보


* 데이터베이스 링크 : USER_DB_LINKS  링크에 관련된 정보


* 스냅샷 : USER_SNAPSHOTS


* 스냅샷 로그 : USER_SNAPSHOT_LOGS


* 트리거 : USER_TRIGGERS


* 프로시저, 함수 및 패키지 : USER_SOURCE


* 코드 오류 : USER_ERRORS


* 테이블스페이스 : USER_TABLESPACES


* 영역 할당량 : USER_TS_QUOTAS
   테이블스레이스 단위로 사용자가 이용할 수 있는 영역의 최대크기와
   할당된 영역의 크기 파악에 대한 정보


* 세그먼트와 익스텐트 : USER_SEGMENTS 와 USER_EXTENTS


* 여유 영역 : USER_FREE_SPACE   현재 여유로 표시된 영역이 얼마인지에 대한 정보


* 사용자 : USER_USERS


* 자원 제한량 : USER_RESOURCE_LIMITS


* 테이블 권한 : USER_TAB_PRIVS


* 열 권한 : USER_COL_PRIVS


* 시스템 권한 : USER_SYS_PRIVS

'DB' 카테고리의 다른 글

SQL loader 사용하기  (0) 2008.09.19
토드 단축키  (0) 2008.09.16
ORA-01031 권한이 없음  (0) 2008.09.15
ORA-27121 unable to determine size of  (0) 2008.09.15
Oracle 환경변수  (0) 2008.09.15
Posted by marryjane
|

ORA-01031 권한이 없음

DB 2008. 9. 15. 19:50

ORA-01031: insufficient privileges

테이블 생성 및... 등등등 권한이 없을 때

'DB' 카테고리의 다른 글

토드 단축키  (0) 2008.09.16
데이터 사전정보  (0) 2008.09.15
ORA-27121 unable to determine size of  (0) 2008.09.15
Oracle 환경변수  (0) 2008.09.15
기본으로 생성되는 Role  (0) 2008.09.15
Posted by marryjane
|