-
함수와 스택 메모리Java 2023. 2. 12. 17:39
스택을 이해할려면 메모리 구조를 이해할 필요가 있다.
메모리의 공간은 크게 Stack영역, Heap 영역으로 구분되고 데이터타입(자료형)에 따라서
해당 공간에 할당된다.
Stack 영역
앞에 작성하던 메소드 내에서 정의하는 기본 자료형(int, double, byte, long, boolean)에 해당되는 지역변수(매개변수 및 블럭문 내 변수 포함)의 데이터의 값이 저장되는 공간이 stack영역이다.
즉 메소드 내에서 정의하는 기본 자료형에 해당되는 지역변수의 데이터 값이 저장되는 공간
메소드가 호출될때 스택 영역에 스택프레임이 쌓이게 되고 그안에 메소드를 호출한다.
메소드가 호출 될 때 메모리에 할당되고 종료되면 메모리에서 사라진다.
Stack은 후입선출 LIFO(Last-In-First-Out)의 특성을 가지며, 스코프(Scope)의 범위를 벗어나면 스택 메모리에서 사라진다.
스택 프레임
하나의 메서드에 필요한 메모리 덩어리를 묶어서 스택 프레임이라고 한다.
하나의 메서드당 하나의 스택 프레임이 필요하며, 메서드를 호출하기 직전 스택프레임을 자바 Stack에 생성한 후 메서드를 호출하게 된다. 만일 메서드 호출 범위가 종료되면 스택에서 스택프레임이 위에 쌓인것부터 제거된다.
public static void main(String[] args) { int a = 5; a = 4; a = 3; a = 2; System.out.println(a); for(int i=0; i<5; i++){ } // System.out.println(i); 컴파일 에러 }
위의 소스 코드처럼 a라는 변수는 main 메소드가 호출될때 Stack 영역에 할당되고 종료 시 해제된다.
또한 a라는 변수의 값이 5,4,3,2 순으로 값을 할당하였고 출력되는 값은 2가 출력된다.(이전 데이터는 지워지고 2라는 값만 출력하게 된다.) 즉 stack 영역은 변수에 새로운 데이터가 할당되면 이전 데이터는 지워진다는 것을 알수있다.
또한 for문 내에 int i를 정의하였는데 for문이 종료된 다음 i를 출력하지 못하는 이유는 지역변수이므로
for문의 종료와 함께 Stack 영역에서 해제되었기 때문이다.
인스턴스(Instance)
- 클래스는 객체의 속성을 정의하고, 기능을 구현하여 만들어 놓은 코드 상태
- 실제 클래스 기반으로 생성된 객체(인스턴스)는 각각 다른 변수 값을 가지게 된다.
ex) 학생의 클래스에서 생성된 각각의 인스턴스는 각각 다른 이름,학번, 학년등의 값을 가지게 된다
- new 키워드를 사용하여 클래스를 메모리에 생성한 상태
(앞서 참조형 데이터 타입과 new에 대한 개념을 잡고 이해하고 보면 이해가 간다.)
String str1 = "string"; String str2 = "string"; System.out.println(str1==str2); //true String str3 = new String("string"); String str4 = new String("string"); System.out.println(str3==str4); //false
앞서 본 new 키워드 사용을 봤을때 값이 같더라도 heap영역에 새로운 메모리영역에 저장이 되어 각각 다른 메모리 주소를 가지게 된다.
new 키워드 이해를 위해 다른 코드 소스를 작성해보았다.
package ch01; public class student { // 상태(속성) (멤버변수) int studentId; String studentName; String address; double height; //0.0 boolean isMarried; // 기능 // 공부한다. public void study() { System.out.println(studentName + "학생이 공부를 합니다."); } //휴식한다. public void breakTime() { System.out.println(studentName +"학생이 휴식을 합니다."); } public void showInfo() { System.out.println("============상태창=============="); System.out.println("학생에 ID값은 : " + studentId); System.out.println("학생에 이름은 : " + studentName); System.out.println("학생에 주소는 : " + address); System.out.println("==============================="); } //함수와 메서드의 차이점 //메서드란 //자바에서 메서드란 객체의 기능을 구현하기 위해서 클래스 내부에 구현되는 메서드 //멤버 함수(member function) //결론 : 메서드는 자신에 변수를 활용해서 객체의 기능을 구현하는 것 // 학생의 기능(메서드) 3가지 정의해주세요. public void working() { System.out.println(studentName+"학생이 운동을 합니다."); } public void chleaning() { System.out.println(studentName+"학생이 청소를 합니다."); } public void playing() { System.out.println(studentName+"학생이 열심히 놉니다."); }
package ch01; public class MainTest1 { // 메인 함수 - 코드의 시작점 public static void main(String[] args) { // The local variable studentKim may not have been initialized // 데이터 타입 - 사용자 정의 타입(대문자 --> 참조 타입) Student studentKim = new Student(); studentKim.studentId = 1; studentKim.studentName = "홍길동"; studentKim.address = "부산시 해운대구"; studentKim.study(); studentKim.breakTime(); studentKim.showInfo(); System.out.println("--------------------"); Student studentLee = new Student(); studentLee.studentName = "이순신"; studentLee.studentId = 2; studentLee.address = "부산시 진구"; studentLee.study(); studentLee.breakTime(); } // end of main } // end of class
출력값
홍길동학생이 공부를 합니다.
홍길동학생이 휴식을 합니다.
============상태창==============
학생에 ID값은 : 1
학생에 이름은 : 홍길동
학생에 주소는 : 부산시 해운대구
===============================
------------------------------
이순신학생이 공부를 합니다.
이순신학생이 휴식을 합니다.위의 소스 코드를 보면 new 키워드를 사용해 홍길동,이순신이라는 학생의 메모리가 heap 영역에 따로 메모리를 할당받아 값을 저장하고 출력 되는것을 볼수있다.
힙(Heap)
생성된 인스턴스는 동적 메모리에 할당된다.
하나의 클래스로부터 여러개의 인스턴스가 생성되고 각각 다른 메모리 주소를 가지게 된다.
주기적으로 사용하지 않으면 메모리를 수거한다.
정리
스택은 함수가 호출될 때 지역 변수들이 사용하는 메모리이며 함수의 수행이 끝나면 위에서 부터 함수가 사용한 메모리 공간은 자동으로 사라지게 된다.
인스턴스는 객체의 속성의 정의하고,기능을 구현하여 만들어 놓은 상태를 말하며 new 키워드를 써서 heap영역에 메모리 공간을 새로 할당 받는다.
heap영역으로 나누는 이유는 생각해보았을때 Stack영역만 사용하면 중복된 값이 계속 쌓이기 때문에 메모리 공간을 너무 차지해서 주소와 주소값을 구분하여 heap 메모리에 저장후 각자 부르는 방식으로 쓰면 메모리도 안잡아먹고 보다 효율적으로 사용할수 있게 되어서 그렇게 쓰는것 같다.'Java' 카테고리의 다른 글
객체와 객체간에 상호작용 (0) 2023.02.12 생성자 (0) 2023.02.12 함수(function) (0) 2023.02.12 객체 지향 언어 (0) 2023.02.12 반복문 - for,while 조건문 - whitch (0) 2023.02.12