JVM 메모리

Development/Java 2010.11.15 16:54
JVM은 실행될 클래스파일을 메모리에 로드후 초기화작업을 수행한다. 초기화하면서 메소드와 클래스변수 들을 해당 메모리영역에 배치한다. 클래스로드가 끝난후 JVM은 main메소드를 찾아 지역변수 , 객체변수 , 참조변수를 스택에 쌓고 다음 라인을 읽으면서 함수를 호출할것인지 힙에 객체를할당할것인지등.. 여러 작업을 하게됩니다.


JVM 메모리구조

1. 메소드영역 : 메소드의 바이트코드 , 클래스변수가 저장되는 영역

2. 힙 영역 : 프로그램 실행중 생성된 객체가 저장되는 영역

3. 스텍 영역 : 메소드 내의 지역변수 , 매개변수(참조형 제외)가 저장되는 영역

4. pc 레지스터 : jvm이 현제 수행할 명령어의 주소가 저장되는 영역

5. Native메소드 스텍 : JAVA어 외의 다른 언어의 메소드에 매개변수 , 지역변수가 저장되는 영역


메소드영역에 관한 짧막한 설명..
객체를 여러번찍으면 객체 속성변수는 그렇다치고 메소드들은 메소드영역에 찍히게됩니다.
여러 객체를 찍을때마다 메소드가 중복되어 메소드영역에 저장되는게 아니라 하나의 메소드를 가지고
해당클래스의 객체가 그 메소드를 공유하여 사용한다는것입니다. 사용할때는 메소드를 호출할때 객체의 정보를 일부 포함시켜 넘겨주어 어떤 객체의 메소드를 처리할것인가를 구별합니다. 이는 프로그래머가 하는게아니라 JVM내부적으로 일어나는 일이기때문에
크게 신경쓰지 않아도 되는일입니다. 다른 예를 들자면 메소드영역에는 클래스변수가 저장되는데 이또한 객체가 공유하는 변수가 되겠습니다.

======================================================================================




출처 -  http://www.cyworld.com/crazyprogram/4896771 
========================================================================================

● 자바 메모리(JVM) 구조

1. 상속관계를 이용하여 메모리 구조를 이해해 보자.

부모(Parent, Base, Super)와 자식(Child, Derived, Sub)은 계층 구조를 이룬다.

 

1) 메모리 특징

  • 힙영역: 자식을 생성하면 반드시 부모도 생성된다(아래 그림에서 자식 A가 메모리에 올라갈때 A와 Parent가 같이 올라간다).
  • 스태틱영역(Method Area) : 자식의 설계도가 올라가면 부모의 설계도도 같이 올라간다. 

    - 모든 메서드(클래스 메서드, 인스턴스 메서드)는 스태틱영역에 로드된다. 하지만 여기서 클래스 메서드인 경우는 인스턴스 생성없이 클래스 이름으로 바로 호출 가능하고 인스턴스 메서드는 객체를 생성해야 한다. 인스턴스 메서드는 인스턴스 변수를 사용하기 때문이다.!!!!

    - 생성된 객체의 참조 주소는 부모의 주소다.

         

A a2=new A();

에서 a2를 살펴보자. 설계도영역에 올라간 A 타입은 Parent 타입의 자식이므로 A가 메모리에 설계도 영역에 올라가면 부모 Parent도 같이 올라간다. 그리고 힙영역에 A 객체가 생성되면 부모인 Parent의 객체도 생성되며 레퍼런스 a2는 부모 Parent의 주소를 참조한다.

[출처] 메모리 구조 기본 (1)-섹션 143|작성자 자바자바

 

http://blog.naver.com/honnynoop/22805940 -

 

 

 2. 객체 생성시에 메모리 구조를 이해해보자 

 

 

 인스턴스 생성시 각 인스턴스 멤버는 새로운 메모리(Heap 영역)에 할당 되지만 인스턴스 메소드는 Method 영역에 있는 하나를 공유한다. 메소드는 한 개만 존재하는데 메소드가 호출되면 제어가 메소드로 정의로 넘어 가는데 어떻게 인스턴스 멤버를 구분해서 해당 인스턴스 멤버의 내용을 출력할까?

이 의문에 대한 열쇠가 바로 래퍼런스 this이다.

자바의 모든 인스턴스 메서드(생성자 포함)는 this(레퍼런스 변수)를 기본적으로 가지고 있다가 해당 메서드을 호출한 매서드의 this(레퍼런스 변수)의 값을 넘겨받는다. 메서드에서 사용되는 모든 필드는 사실은 this로 접근하는 것이다.

------------------------------

인스턴스 메서드(생성자 포함)는 자신을 호출한 메서드의 this값을 넘겨 받는다.

여기서 문제가 두개 보였다.

1. 하나의 (1)메서드가 다른 (2)메서드에게 this값을 넘겨 준다고 생각하면 (2)다른메서드가 (3)또다른메서드를 호출하게 되면 자신의 this값을 어떻게 넘겨 주냐 하는 문제가 발생한다. 두번째 메서드에는 이미 첫번째 메서드의this 값을 갖고 있는데….

2. this가 자신의 인스턴스를 가리킨다. 즉 멤버필드와 메서드필드가 다른 영역에 저장되는데 this로 어떻게 이 둘을 다 가리킬 수 있는지를…. .. 생각해보는것이..  

 

 

예제를 메모리화 해보자!!

public class Main {

public static void main(String[] args) {

Operation test = new Operation();

Point A1=new Point(100,100);

static int mul=0;

test.setX(10);

test.setY(20);

System.out.println(text.add());

System.out.println(Operation.multi(10, 20));

}

}

public class Point {

private int x;

private int y;

public Point() { this(0, 0); }

public Point(int x, int y) {

setX(x);

setY(y);

}

public int getX() { return x; }

final void setX(int x) { this.x = x; }

public int getY() { return y; }

final void setY(int y) { this.y = y; }

}

public class Operation extends Point{

int sum=0;

public Operation(){ super(0,0); }

public int add(){

sum = super.getX()+super.getY();

return sum;

}

static int multi(int a, int b){

mul = a *b;

return mul;

 

}

 

개념적으로...

 

 

메모리 구조

 

1. new 연산자를 통해 Heap 인스턴스가 생성되었다. 그리고 클래스 변수인 mul 초기화 되었다.

 

 

 

2. test.setX(10)와 test.setY(20)으로 Heap Area 있는 인스턴스 멤버를 초기화 한다. 각 멤버의 접근지정자가 private이기 때문에 다른 클래스에서 접근할 수 있도록 메서드를 만듬. getX()와 getY()메서드는 출력을 위해. (A1 인스턴스 제외)

 

 

3. add() 메서드는 인스턴스 메서드이기 때문에 참조변수로 접근 this.add();

X=10, y=20 초기화 했던 것을 더한다.

 

 

4. mutil()는 클래스 메서드이기 때문에 클래스명으로 접근. Operation.mutil();

 

 

출처 -  http://force44.blog.me/130095188664 
 
Posted by linuxism

댓글을 달아 주세요