ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 자바 기초 01 - 메모리/자바실행원리/일반변수-지역변수
    자바 기초 2021. 10. 28. 11:22

    유투버 '데어프로그래밍'님 강의 참조

     

     

     

     

    01 컴퓨터의 기본 구조

    1. 메모리
      컴퓨터의 저장 영역 또는 공간. 이 공간에는 각각의 주소가 있고 이 공간에 데이터를 저장하게 된다. 이제 이 공간에 있는 데이터로 '연산'이라는걸 진행하고싶으면 'CPU'가 필요 하다.
    2. CPU
      CPU가 필요한 데이터를 주소를 통해 접근 하고 연산을 한 뒤 다시 메모리의 빈공간에 연산이 된 새 데이터를 넣는다. 
    3. 모니터
      이러한 연산 혹은 컴퓨터가 진행한 작업물들을 화면으로 나타내고 싶을 때 모니터를 통해서 표현 가능 하다. 

     

    02 프로그래밍 메모리

    • 프로그래밍에서의 메모리의 영역은 논리적으로 3개의 공간으로 나눠서 관리 되게 된다. (Satitc/heap/stack)
    • 프로그램을 만들 때 어떠한 영역 혹은 기능들이 각각 static/heap/stack으로 들어가는지를 이해할 필요가 있다.

    ※ 예로 '음료수 빨리 마시기' 게임을 만든다고 가정 하자. 

    • 필요한 기능들은 다음과 같다 → 음료수 기계, 참가자, 음료수 마시기(행위-몇초가 걸리나)
      여기서 각각의 기능들이 언제부터 언제까지 존재를 해야하는지를 이해해야 한다. 
    1. 음료수 기계 - 기계는 게임 처음부터 끝까지 존재해야 참가자들이 음료수를 받을 수 있고 음료수마시기라는 행위가 이루어 질 수 있기 때문이다. 그래서 음료수 기계 부분은 'Static 영역'에 들어 간다.

      Static 영역 - 여기에 들어있는 기능들은 프로그램 시작과 종료될때까지 메모리 'Static' 영역에 올려놓고 소멸시키지않고 계속해서 쓰게 한다. 왜? 프로그램 전반에 걸쳐 끝까지 필요한 기능이기 때문. 또한 Static 영역의 부하가 메모리에서 가장 크다. 

    2. 참가자 - 참가자는 게임이 시작되면 음료수를 받고 음료수 마시기 행위를 하고 없어 진다. 즉 필요한 시점에 등장하여 어느 시점에서 기능을 다하면 사라 진다. 즉 절대로 'Static 영역'에는 들어 갈 수 없고 동적으로 생겼다가 없어지기 때문에 'Heap 영역'에 들어 간다. 

      Heap 영역 - 여기의 기능들은 프로그램이 필요할때 Heap영역에 올라가 사용되고 어느 시점에서의 기능이 다하면 Heap영역을 포함해서 메모리에서 사라 진다. 동적인 할당이 필요한 메모리들이 올라 간다. Heap 영역은 Staic 영역보다 생명 주기가 짧다. 

    3. 음료수 마시기 - 이 행위는 정말 잠깐 나왔다가 순식간에 사라진다. 참가자가 필요하고 참가자가 음료수를 받아야 행위가 진행 될 수 있고 참가자가 음료수를 다 마시면 행위는 끝나게 된다. 정말 잠깐뜨고 사라지는 기능들이 'Stack 영역'에 들어 간다

      Stack 영역 - 가장 생명주기가 짦으며 보통 여기의 기능들은 프로그램 전반에 걸쳐 아주 잠깐 필요하므로 이 메모리 영역에 속해진다. 

     

     

     

    03 자바 코드 실행 원리

    • 아래의 코드를 보면서 이해를 해보자
    package ch01;
    
    int n3 = 30;
    
    public class VarEx02 {
    	
    	int n2 = 20;
    
    	public static void main(String[] args) {
    		int n1 = 10;
    		System.out.println(n1);
    		System.out.println(n2);
    	}
    }
    1. 자바의 모든 코드는 클래스 내부에 존재 해야 한다. class를 벗어난 코드는 컴파일 에러를 일으킨다 (int n3)
    2. 자바는 실행전에 static 이라는 키워드를 가지고 있는 모든 기능들을 static 메모리 공간에 로드 한다
    3. 자바프로그램을 실행하면 main() 함수가 메모리에 올라가게되고 main()함수 내부를 실행 한다
    4. main()함수의 내부가 끝나면 자바프로그램은 종료 된다. 
      더보기
      int n3 = 30 은 클래스를 벗어낫기때문에 오류.
      int n2 = 20 의 경우는 메모리에 현재 떠 있지 않기 때문에 오류. 
      int n2 를 메모리에 띄울수 있는 방법은 2가지
      1) static 영역에 넣기
      2) static int n2 로 static 할당 

     

     

     

     

    04 일반변수와 레퍼런스(지역/참조)변수

    //MyData는 Runtime이 될때 힙에 할당이 되면서 사이즈가 부여 된다
    class MyData {
    	int id = 1;
    	int price = 1000;
    }
    
    public class VarRefEx01 {
    	
    	public static void main(String[] args) {
    		//타입 변수; -> 단순 변수 선언
    		//타입 변수 = 값 -> 변수 초기화 = 메모리에 할당
    		int num = 10; //일반 변수 (크기가 정해져 있는 것 = 컴파일 시점)
    		MyData m = new MyData(); // 레퍼런스 변수 (크기가 정해져 있지 않는 것 = 컴파일 시점)
    		
    		System.out.println(m.id * 20);
    		System.out.println(m.price * 3);
    	}
    }
    • 일반변수와 레퍼런스변수의 차이점은 컴파일 시점에 크기가 정해져 있냐 없느냐 이다. 타입이 바로 붙은 변수는 컴파일이 안되도 타입이 붙어 있기때문에 크기를 알 수 있다. 하지만 Class형태로 선언된 객체의 내부는 무조건 실행이 되어 힙에 할당이 되어 사이즈가 부여가 되어야 그 크기를 알 수 있다. 
    • 커스텀 타입 즉 개발자가 직접 만드는 Class형태의 타입들은 무조건 4byte가 할당이 되는데 이 할당이 될때에는 내용을 메모리에 올리는게아니라 heap공간의 주소를 4byte로 할당하여 올려놓고 필요할때 heap 공간의 주소를 찾아가서 꺼내오는 형태이다. 즉 Mydata m 에서 m은 4byte로 할당 된 주소영역을 가르키고 다시 한번 이 주소를 가지고 heap영역으로 가서 꺼내오는 형태
    • 자바에서 일반변수는 기본 자료형(8 가지)으로 크기를 미리 알 수 있고 레퍼런스변수는 class 자료형태(bean)등으로 크기를 미리 알지 못하는 변수. 

     

     

     

    05 Stack 메모리

    • 먼저 두가지 자료구조를 알아보자 1)큐 2)스택. (자료구조의 뜻은 자료를 저장할 수 있는 구조)
    • 큐의 경우는 들어오는 순서와 처리되는 순서가 동일 하다 (1,2,3 으로 들어오고 처리도 1,2,3 순으로 된다.) 스택의 경우는 반대이다. (1,2,3 으로 들어오지만 처리는 3,2,1 순으로 된다)

    이제 아래의 코드를 보면서 이해해보자

    public class StackEx01 {
    	
    	static void a() {
    		StackEx01.b();
    		System.out.println("a2");
    		System.out.println("a3");
    		System.out.println("a4");
    	}
    	
    	static void b() {
    		System.out.println("b1");
    		System.out.println("b2");
    		System.out.println("b3");
    	}
    	
    	public static void main(String[] args) {
    		System.out.println("m1");
    		System.out.println("m2");
    		StackEx01.a();
    		System.out.println("m4");
    		System.out.println("m5");
    	}
    }

    • 자바프로그램의 실행 순서
      StackEx01.Java → 컴파일(해석) →  StackEx01.class 변환 → JVM 전달
    • JVM으로부터의 중요한 개념 여기서 큐와 스택 영역으로 나뉘어서 실행 됨
      1) .class 로드 → static 찾기 → static 메모리 공간 할 당 후 static이 있는 기능들을 메모리에 올림(내부는 올리지 않음) a()/b()/main()
      2) main() 메서드 실행 → main()내부 영역 코드 실행 (이때 큐 영역에 모든 mainI() 함수의 코드가 들어감, 그리고 스택영역도 따로 생기면서 main()함수 영역이 제일 첫번째로 쌓임) → 차례대로 읽으면서 StackEx01.a(); 까지 읽음 
      3) StackEx01.a() 실행 되면서 a()함수는 큐 영역에 들어가고 a()함수 내용을 차례대로 실행 → 스택영역에는 main() 위에 a()가 쌓임 
      4) a()를 실행해보니 b()를 호출 하고 있음 → 또 다시 b()는 큐와 스택에 쌓임 →  b() 내용은 단순 출력이므로 실행 됨 → 실행 이후 스택으로 돌아가서 a()가 가진 나머지 내용을 실행 함 → 끝나고 다시 main()의 남은 내용을 출력 함

Designed by Tistory.