반응형

자바에서 사용되는 Stack Trace를 알아보자
하나의 프로그램을 수행하는 동안 스레드는 다양한 메서드를 돌아다니게 된다.
메서드가 호출되고 종료되면, 메서드를 호출하는 곳으로 다시 돌아가게 된다.
이렇게 호출된 곳으로 다시 돌아가기 위해서는 Stack에 메서드가 호출된 포인트를 기록해야,
그 기록을 따라서 다시 돌아갈 수 있게 된다.
프로그램 실행 중 기록되는 특정 포인트들을 쌓아놓고 활용하는 것이 Stack Trace가 되겠다.
디버깅을 수행할 경우에 유용하게 활용될 수 있다.

프로그램이 수행될 경우, 여러 클래스를 돌아다니면서 작업을 하게 될 수 있다.
이 때, 버그가 발생하면 수많은 메서드 호출을 디버깅과정는 과정을 거쳐야 한다.
버그가 발생되는 곳으로 예상 되는 곳에서 Stack Trace를 하면 어디에서 예상 지역을 호출하는지 알 수 있다.

JAVA Stack Trace 방법
Thread를 이용하여 현재 Thread를 얻어오고, 얻어온 Thread로부터 Stack Trace를 가져온다.
Thread th = Thread.currentThread();
StackTraceElement 배열을 이용하면 받을 수 있게 된다.
StackTraceElement[] lists = th.getStackTrace();
StackTraceElement의 메서드를 이용하여 원하는 내용을 출력하면 된다.
예제에서는 getClassName()과 getMethodName()을 이용한다.

예제를 보자.
public class StackTraceElementTest {
    public void test1(){
        test2();
    }
 
    public void test2(){
        test3();
    }

    public void test3(){
        test4();
    }
 
    public void test4(){
        Thread th = Thread.currentThread();
        StackTraceElement[] lists = th.getStackTrace();
        for(StackTraceElement list : lists){
            System.out.println(list);
            System.out.println(list.getClassName() + " : " + list.getMethodName());
        }
    }
 
    public static void main(String[] args){
        StackTraceElementTest test = new StackTraceElementTest();
        test.test1();
    }
}


위의 예제는 main - test1 - test2- test3- test4를 차례로 호출하고 있다.
test4에서 Stack Trace를 수행하면 다음과 같은 결과가 출력된다.

java.lang.Thread : getStackTrace
JavaStudy.StackTraceElementTest : test4
JavaStudy.StackTraceElementTest : test3
JavaStudy.StackTraceElementTest : test2
JavaStudy.StackTraceElementTest : test1
JavaStudy.StackTraceElementTest : main


getStackTrace를 사용한 지점부터 역순으로 출력을 하게 되므로, main - test1 - test2- test3- test4의 순서로 호출됨을 알 수 있다.


출처 : http://okjkillo.tistory.com/entry/JAVA-Stack-Trace

반응형

'Java기초' 카테고리의 다른 글

Browser별 file name깨짐현상  (0) 2014.08.13
replace replaceAll 차이  (0) 2014.08.01
JVM 메모리  (0) 2014.04.30
정규식 특수문자  (0) 2013.07.15
추상클래스 인터페이스 차이2  (0) 2013.07.11
반응형

1. 메모리

 

프로그램을 실행하기 위한 데이터 및 명령어를 저장하는 공간

 

※ 메모리구조를 공부하는 이유
- 같은 기능의 프로그램이더라도 메모리 관리에 따라 성능이 좌우됨.
- 메모리 관리가 되지 않은 경우 속도저하 현상이나 튕김 현상 등이 일어날 수 있음.
- 한정된 메모리를 효율적으로 사용하여 최고의 성능을 내기 위함.

 

2. 자바 프로그램의 실행구조

 

프로그램이 실행되기 위해서는 windows나 linux같은 운영체제(OS)가 제어하고 있는 시스템의 리소스의 일부인 메모리(RAM : 주기억장치)를 제어할수 있어야 하는데, java이전의 c같은 대부분의 언어로 만들어진 프로그램은 이러한 이유때문에 OS에 종속도어 실행되게 되어 있었다.   

 

java프로그램은 JVM(Java Virtual Machine : 자바가상머신)이라는 프로그램만 있으면 실행이 가능한데, JVM이 OS에게서 메모리 사용권한을 할당받고 JVM이 자바프로그램을 호출하여 실행하게 된다. OS한태서는 독립되었지만 JVM이라는 프로그램에 종속적이게 된다. (JVM을 실행시키고 다시 JVM이 프로그램을 실행시키는 방식이다 보니 OS에 직접 제어받는 방식보다는  속도면에서는 느리다는 단점을 가진다)

 

 

 

 

* JVM이란?

- Java Virtual Machine
- JAVA와 OS 사이에서 중계자 역할
- JAVA가 OS에 구애받지 않고 재사용을 가능하게 해 줌
- 메모리 관리 기능(Garbage Collection)

 

3. 자바프로그램 실행 과정과 JVM메모리 구조

 

프로그램이 실행되면, JVM은 OS으로부터 이 프로그램이 필요로 하는 메모리를 할당받고, JVM은 이 메모리를 용도에 따라 여러 영역으로 나누어 관리한다.

 

 

- JAVA Source : 사용자가 작성한 JAVA 코드
- JAVA Compiler : JAVA 코드를 Byte Code로 변환시켜주는 기능
- Class Loader : Class파일을 메모리(Runtime Data Area)에 적재하는 기능
- Execution Engine : Byte Code를 실행 가능하게 해석해주는 기능
- Runtime Data Area : 프로그램을 수행하기 위해 OS에서 할당 받은 메모리 공간

 

4. Runtime Data Area


① Class Area

 

 

 

- Method Area, Code Area, Static Area 로 불리어짐

i) Field Information : 멤버변수의 이름, 데이터 타입, 접근 제어자에 대한 정보

ii) Method Information : 메서드의 이름, 리턴타입, 매개변수, 접근제어자에 대한 정보

iii) Type Information : - Type의 속성이 Class인지 Interface인지의 여부 저장
- Type의 전체이름(패키지명+클래스명)
- Type의 Super Class의 전체이름
(단, Type이 Interface이거나 Object Class인 경우 제외)
- 접근 제어자 및 연관된 interface의 전체 리스트 저장

iv) 상수 풀(Constant Pool)
- Type에서 사용된 상수를 저장하는 곳(중복이 있을 시 기존의 상수 사용)
- 문자 상수, 타입, 필드, Method의 symbolic reference(객체 이름으로 참조하는 것)도 상수 풀에 저장

v) Class Variable
- Static 변수라고도 불림
- 모든 객체가 공유 할 수 있고, 객체 생성 없이 접근 가능

vi) Class 사용 이전에 메모리 할당
- final class 변수의 경우(상수로 치환되어) 상수 풀에 값 복사

 

② Stack Area

 

 

 

- Last In First Out (LIFO)
- 메서드 호출 시마다 각각의 스택프레임(그 메서드만을 위한 공간)이 생성
- 메서드 안에서 사용되어지는 값들 저장, 호출된 메서드의 매개변수, 지역변수, 리턴 값 및 연산 시 일어나는 값들을 임시로 저장
- 메서드 수행이 끝나면 프레임별로 삭제

 

③ Heap Area

 


 

- new 연산자로 생성된 객체와 배열을 저장하는 공간
- 클래스 영역에 로드된 클래스만 생성가능
- Garbage Collector를 통해 메모리 반환

i) Permanent Generation
- 생성된 객체들의 정보의 주소 값이 저장된 공간

ii) New Area
- Eden : 객체들이 최초로 생성되는 공간
- Survivor : Eden에서 참조되는 객체들이 저장되는 공간

iii) Old Area : New Area에서 일정시간이상 참조되고 있는 객체들이 저장되는 공간

 

④ Native method stack area


- 자바 외의 다른 언어에서 제공되는 메서드들이 저장되는 공간

 

⑤ PC Register


- Thread가 생성 될 때마다 생성되는 공간
- Thread가 어떤 부분을 어떤 명령으로 실행할 지에 대한 기록
- 현재 실행되는 부분의 명령과 주소를 저장

 

5. Garbage Collection


- 참조되지 않은 객체들을 탐색 후 삭제
- 삭제된 객체의 메모리를 반환
- Heap 메모리의 재사용

 

① Minor Garbage Collection

 

i) New 영역에서 일어나는 Garbage Collection
ii) Eden영역에 객체가 가득 차게 되면 첫 번째 Garbage Collection 발생
iii) Survivor1 영역에 값 복사
iv) Survivor1 영역을 제외한 나머지 영역의 객체들을 삭제
v) Eden영역과 Survivor1영역의 메모리가 기준치 이상일 경우, Eden 영역에 생성된
객체와 Survivor1영역에 있는 객체 중 참조되고 있는 객체가 있는지 검사
vi) 참조되고 있는 객체를 Survivor2 영역에 복사
vii) Surviver2 영역을 제외한 영역의 객체들을 삭제
viii) 일정시간이상 참조되고 있는 객체들을 Old영역으로 이동
ix) 반복

 

② Major Garbage Collection (Full Garbage Collection)

 

i) Old영역에 있는 모든 객체들을 검사
ii) 참조되지 않은 객체들을 한꺼번에 삭제
iii) Minor Garbage Collection에 비해 시간이 오래 걸리고 실행 중 프로세스가 정지


출처 : http://huelet.tistory.com/entry/JVM-%EB%A9%94%EB%AA%A8%EB%A6%AC%EA%B5%AC%EC%A1%B0


반응형

'Java기초' 카테고리의 다른 글

replace replaceAll 차이  (0) 2014.08.01
java stack trace  (0) 2014.05.09
정규식 특수문자  (0) 2013.07.15
추상클래스 인터페이스 차이2  (0) 2013.07.11
인터페이스 추상클래스  (0) 2013.07.11
반응형


1) .

  : 어떤 문자이건 간에 임의의 한 글자를 나타냄

  

2) * 

  : 바로 앞의 문자를 의미하며 그 문자가 없거나 하나 이상임을 나타냄

  

3) +

  : 바로 앞의 문자를 의미하며 그 문자가 하나 이상임을 나타냄

  

4) ?

  : 바로 앞의 문자가 없거나 혹은 있음을 나타냄


5) ^

  : 바로 뒤의 문자열을 기준으로 이것과 동일한 문자열로 시작되는 것을 가리킴

    

6) $

  : 문자열의 맨 마지막을 가리킴

  

7) []

  : 각괄호는 [] 안에 있는 문자열 중에서 하나의 문자만을 의미함

    [] 안에서 범위를 지정할 때는 '-' 문자를 사용함

    만일 원하지 않는 문자를 제외한 나머지 문자를 가리킬 때에는 []안의 첫 문자로 '^' 를 사용함

    

8) {} 

  : 중괄호 {} 는 {} 앞에 있는 문자나 문자열의 개수를 결정

  

9) ()

  : () 앞에 있는 글자들을 그룹화 한다.



반응형

'Java기초' 카테고리의 다른 글

replace replaceAll 차이  (0) 2014.08.01
java stack trace  (0) 2014.05.09
JVM 메모리  (0) 2014.04.30
추상클래스 인터페이스 차이2  (0) 2013.07.11
인터페이스 추상클래스  (0) 2013.07.11
반응형

인터페이스.. 추상클래스..추상메소드.. 너무복잡합니다

검색을 해도 잘 정리된 블로그는 이해할수는 있지만 정확히 뭐가뭔지 잘모를때

예제를 살펴보면 정확하게 알수 있습니다

예제를 검색해도 이해하기 어려운 부분이 있을수 있습니다

이럴때!!! 이미 잘 정리된(?) 정리라기 보다는 정의에 가까운 java api를 보면됩니다

우리가 import 해서 쓰는 클래스들 중에서 잘살펴보면 interface와 abstract 클래스와 메소드를 잘 활용한 클래스가 있습니다!

 그전에 최소한 뭐가뭔지는 알아야 되니 간단하게 정의해봤습니다

정의를 읽고난후에 설명드리겠습니다.

인터페이스란 간단히 말해서 클래스끼리 어떤방식으로 데이터를 주고받을것이냐에 대한

동작을 기술한것입니다.

일반적으로 클래스는 설계와 구현을 함께 할수있지만 인터페이스는 순수하게 설계만 하는것입니다.

 그렇다면 인터페이스를 왜 쓰는것일까요? 클래스에다가 설계와 구현을 모두할수있는데

굳이 따로할필요가 있을까라고 생각될겁니다.

예를 들자면 시간을 출력해야하는 상황에서 여러사람들이 시간을 출력하는 로직을 만들때

A라는 사람은 순수하게 시간만출력하자...

B라는 사람은 그래도 정확하게 시와 분까지만 출력하자..

C라는 사람은 무슨소리!? 초까지출력해야지!!

D라는 사람은 나라마다 다른데 나라도 명시해줘야지

라고 각자마자 생각이 다를수있습니다.

이럴때 공통사용방법을 지정하면 어디에서든 동일하게 시간을 출력하는것을 이용할수있을것입니다

(인터페이스에서는 static final 를 통해 변수를 선언할수있습니다)

이렇게 모든 클래스에서 공통으로 사용할 방법을 정의한 특별한 클래스를 interface라고

하는데 이 interface를 사용하기위해서는 implements로 사용한다고 명시해주고

interface에 정의되어있는 모든 메소드를 구현해줘야합니다.

다음으로...

그렇다면 추상클래스란 무엇이냐?

추상메소드가 하나이상 있는 클래스를 말합니다. 그렇다면 추상메소드란  무엇이냐..

public abstract void print(); 이거와 같이 {}가 없는 메소드를 말합니다

여기서 abstract를 빼줘도 에러가안납니다 뒤에 세미콜론인 ;으로 구분해주기때문에

하지만 알아보기쉽게하기위해서 abstract를 붙여주엇네요

추상클래스는 extends를 이용해서 사용할수있습니다

이제 간단한 정의 설명은 마치고 실제로 그렇게 사용되는지 왜그렇게 사용되었는지 알아보겠습니다

jadclipse를 plugin을 통해 설치안한분은 제 블로그에있는 나와있는 jadclipse 플러그인 설치 한후에 하면 훨씬 유용합니다.

일단 아무이유없이 Calender 클래스를 이용하여 날짜를 갑자기 출력하고싶어졌습니다

public class TestInterface {

    public static void main(String[] args) {
        Calendar cal =new Calendar(); //     <---- 하면어떻게될까여? Cannot instantiate the type Calendar 와 같이 오류가 뜹니다
    

    }

}

그렇다면 왜 오류가날까..컨트롤을 누른상태에서 Calender이부분을 왼쪽버튼으로 클릭해줍니다

(jad 설치시에만 가능 jad는 역컴파일러로 .class파일을 .java파일로 바꿔줍니다

그때 .class파일에 정의되어있는 Calender클래스를 보게끔 해주는 역활을 합니다)

윗부분만 조금만 보면 알수있는 사실들이 있습니다

public abstract class Calendar     //사실 1 :사실 Calender클래스는 추상클래스였다....

    implements Serializable, Cloneable, Comparable  //interface 세개를 implements를 사용하여 쓰고있다...
{
    private static class CalendarAccessControlContext
    {

        private static final AccessControlContext INSTANCE;

        static
        {
            RuntimePermission runtimepermission = new RuntimePermission("accessClassInPackage.sun.util.calendar");
            PermissionCollection permissioncollection = runtimepermission.newPermissionCollection();
            permissioncollection.add(runtimepermission);
            INSTANCE = new AccessControlContext(new ProtectionDomain[] {
                new ProtectionDomain(null, permissioncollection)
            });
        }


        private CalendarAccessControlContext()
        {
        }
    }

이러니깐!!! new 를 통해 객체를 못만듭니다. 왜냐고물으신다면 추상클래스는 new를 통해 객체를 생성할수없습니다.

왜냐고물으신다면 그렇게 정외가 되어있습니다.

두번째로 그렇다면 어떻게 쓸수있을까요? 위에 답은 이미나와있습니다..

추상메소들 모조리 몽땅~ 다 구현해주는 겁니다...

그렇다면 그렇게 해봅시다!

어떤가요? Calendar를 new 를 통해 객체생성이됩니다..

다만 좀 구현해줄께 많을 뿐이죠

아니 그렇다면...

public class TestInterface {

    public static void main(String[] args) {
//        Calendar cal =Calendar.getInstance();
      
           
        Calendar cal = new Calendar() {
           
            @Override
            public void roll(int i, boolean flag) {
                // TODO Auto-generated method stub
               
            }
           
            @Override
            public int getMinimum(int i) {
                // TODO Auto-generated method stub
                return 0;
            }
           
            @Override
            public int getMaximum(int i) {
                // TODO Auto-generated method stub
                return 0;
            }
           
            @Override
            public int getLeastMaximum(int i) {
                // TODO Auto-generated method stub
                return 0;
            }
           
            @Override
            public int getGreatestMinimum(int i) {
                // TODO Auto-generated method stub
                return 0;
            }
           
            @Override
            protected void computeTime() {
                // TODO Auto-generated method stub
               
            }
           
            @Override
            protected void computeFields() {
                // TODO Auto-generated method stub
               
            }
           
            @Override
            public void add(int i, int j) {
                // TODO Auto-generated method stub
               
            }
        };

    }

}

이렇게 많이 구현해주는데 시간이 많이 걸리는데..

왜 굳이 추상클래스를 사용하느냐라고 궁금할수있습니다

그런데.. 이렇게 대부분의 블로그들에서 공통된 오류가 있습니다...

추상클래스를 사용하기위해서는 abstract로 구현된 메소드를 오버라이딩해서 써야된다고하는데 사실 다른방법이 있습니다

import java.util.Calendar;

public class TestInterface {

    public static void main(String[] args) {


        Calendar cal = Calendar.getInstance();

    }

}  
이것입니다 getInstance()메소드가 무엇이길래 그러느냐..

그렇다면 봅시다!

    public static Calendar getInstance()

    {
        Calendar calendar = createCalendar(TimeZone.getDefaultRef(), Locale.getDefault());
        calendar.sharedZone = true;
        return calendar;
    }

먼진몰라도(여기서 캡슐화의 특징이 나옵니다. 안에있는 로직이 어떻게 돌아가는지몰라도 이메소드를 쓰면 어떤결과가 나오겠구나.. 하는 아~주 좋은 점이죠)

) calendar를 생성해줍니다.

static이라는 것은 new의 선언 없이 객체를 생성할수 있게끔 해줍니다.getInstance메소드를 통해서요!

그렇다면 여기서 잠깐 추상클래스와 추상메소드를 정리해보면

추상클래스는 extends 를 통해 쓸수있는데 쓰기위해서는 오버라이딩 해줘야한다. 그렇지만 static과 적절한 메소드를 통해 오버라이딩을 해주지 않아도 쓸수있다.

 추상메소드란 추상클래스안에있는 것인데 {}와 {}안에 내용이 없는 메소드이다.

 그렇다면 이제 마지막으로 인터페이스란 무엇이냐

public abstract class Calendar    
    implements Serializable, Cloneable, Comparable  //이부분의 인터페이스를 살펴보겠습니다
{
    private static class CalendarAccessControlContext
    {

        private static final AccessControlContext INSTANCE;

        static
        {
            RuntimePermission runtimepermission = new RuntimePermission("accessClassInPackage.sun.util.calendar");
            PermissionCollection permissioncollection = runtimepermission.newPermissionCollection();
            permissioncollection.add(runtimepermission);
            INSTANCE = new AccessControlContext(new ProtectionDomain[] {
                new ProtectionDomain(null, permissioncollection)
            });
        }


        private CalendarAccessControlContext()
        {
        }
    }

 

package java.io;


public interface Serializable
{
}

 

package java.lang;

// Referenced classes of package java.lang:
//            Object

public interface Cloneable
{
}


package java.lang;

// Referenced classes of package java.lang:
//            Object

public interface Comparable
{

    public abstract int compareTo(Object obj);
}

어떻습니까? 한번 보는것이 여러번 설명하는것보다 눈에 잘들어오죠...

인터페이스를 정의하는데 순수하게 뼈대만을 설계하고 있습니다. 가장 기본적인 뼈대죠..

이보다 완벽한 예제는 없는것 같습니다.(제가 만든 예제는 아니고.. 기업에서 만든것이죠...)

제가 설명해드리고 싶었던것은 나무를 보는 것보다 숲을 보는 것이 이해가 빠른것같네요...

저도 사실 interface가 뭔지 추상클래스가 뭔지 이 글을 쓰기전에는 10의 1정도만 알고있었습니다.

어찌됫든 디컴파일러의 위력을 다시한번 느낄수있는 글인였던것같습니다


출처 http://seodh007.tistory.com/23

반응형

'Java기초' 카테고리의 다른 글

replace replaceAll 차이  (0) 2014.08.01
java stack trace  (0) 2014.05.09
JVM 메모리  (0) 2014.04.30
정규식 특수문자  (0) 2013.07.15
인터페이스 추상클래스  (0) 2013.07.11
반응형
추상 클래스
- 상속 관계에 있는 클래스 중에서 상위 클래스에서는 특별한 구현 없이 사용하고자 하는 메소드만 기술하고,
   구체적인 구현은 하위 클래스에서 하도록 함. 구체적인 내용없이 모양만 갖춘 클래스

> 추상 메소드를 가진 클래스로, new 연산자로 객체 생성할 수 없습니다.

> 따라서, 추상 클래스의 추상 메소드는 자신이 직접 이용하지 못하고, 반드시 하위 클래스에서 이 메소드를 상속받아 구현해야 합니다.

> 추상클래스의 추상 메소드는 반드시 Overriding 되어야 하기 때문에,

   하위 클래스들이 특정 메소드를 반드시 구현하도록 강제할 수 있습니다.

   그리고, 추상 메소드를 오버라이딩 하지 않으면 상속받는 클래스는 자동으로 추상 클래스가 됩니다.

 > 추상 클래스는 일반 메소드와 추상 메소드를 모두 포함 할 수 있습니다.



인터페이스

> Java는 다중상속을 지원하지 않는대신, 다중상속과 유사한 기능이 있는 Interface를 제공합니다.

> Interface는 모든 메소드가 추상메소드이며, 데이터는 final static 변수만을 가지는 특별한 형태이다.



차이점

1) 인터페이스는 다중 상속을 지원하나 추상 클래스는 단일 상속만 가능하다.
2) 추상 클래스에서는 메소드의 부분적인 구현이 가능하지만 인터페이스에서는 오직 메소드 선언만 있을 수 있다.



출처  http://dante2k.egloos.com/199169  와 1개의 주소는 ...기억이 안남 곳곳의 정보를 참조


반응형

'Java기초' 카테고리의 다른 글

replace replaceAll 차이  (0) 2014.08.01
java stack trace  (0) 2014.05.09
JVM 메모리  (0) 2014.04.30
정규식 특수문자  (0) 2013.07.15
추상클래스 인터페이스 차이2  (0) 2013.07.11

+ Recent posts