-
멤버변수의 종류와 자바의 메모리 구조(메서드, 스택, 힙)JAVA/개념 - 김영한 강의 2024. 9. 15. 09:49
멤버 변수의 종류
1. 인스턴스 변수: static이 붙지 않은 멤버 변수
- 인스턴스를 만들 때 마다 새로 만들어진다.
class Dog { String name; int age; void bark() { System.out.println(name + " is barking!"); } } public class Main { public static void main(String[] args) { // 클래스 Dog의 인스턴스를 생성 Dog myDog = new Dog(); // myDog는 Dog 클래스의 인스턴스 myDog.name = "Buddy"; myDog.age = 3; // 인스턴스를 통해 메서드 호출 myDog.bark(); // "Buddy is barking!" 출력 } }
* 인스턴스 변수를 사용할 때 주의할점!
캡슐화 (Encapsulation)
- 객체의 데이터를 안전하게 보호: 클래스 내부의 데이터 멤버를 private으로 선언하고, 외부에서 접근할 때는 getter와 setter 메서드를 통해 접근하는 것이 좋다. 이를 통해 데이터를 직접 수정하는 것을 방지하고, 객체의 무결성을 유지할 수 있다.
public class Person { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }
2. 클래스 변수: static이 붙은 멤버 변수
- 클래스 변수, 정적 변수, static 변수 등으로 부른다. 이 용어를 모두 사용한다.
- static이 붙은 멤버 변수는 인스턴스와 무관하게 클래스에 바로 접근해서 사용할 수 있고, 클래스 자체에 소속되어 있다. 따라서 클래스 변수라고 한다.
- 클래스 변수는 자바 프로그램을 시작할 때 딱 1개가 만들어진다. 인스턴스와는 다르게 보통 여러곳에서 공
유하는 목적으로 사용된다.
static 변수는 클래스를 통해 바로 접근할 수도 있고, 인스턴스를 통해서도 접근할 수 있다.
public class Data3 { public String name; public static int count; //static public Data3(String name) { this.name = name; count++; } }
public class DataCountMain3 { public static void main(String[] args) { //인스턴스를 통한 접근 Data3 data4 = new Data3("D"); System.out.println(data4.count); //클래스를 통합 접근 System.out.println(Data3.count); } }
- data4.count : 인스턴스를 통한 접근
- 추천하지 않음. 인스턴스 변수에 접근하는 것 같아서
- Data3.count : 클래스를 통한 접근
- 정적 변수는 클래스에서 공용으로 관리하기 때문에 클래스를 통해 접근하는 것이 더욱 명확하게 느껴진다.
자바 메모리 구조
1. 메서드(Method) 영역
메서드 영역은 JVM이 시작될 때 생성되며, 프로그램을 실행하는데 필요한 공통 데이터를 관리하여 프로그램의 모든 영역에서 공유한다.
- 클래스 정보: 클래스의 실행코드(바이트 코드), 메서드, 생성자 코드 등 모든 실행코드가 존재
- 정적 변수: static 변수
- 상수 풀(Constant Pool): 클래스와 메서드에 사용되는 상수 값들(문자열 상수, 숫자 상수 등)이 저장된다.
public class Person { public static String species = "Human"; // 정적 변수 public void sayHello() { System.out.println("Hello"); } }
- Person 클래스의 메타데이터와 species 정적 변수는 메서드 영역에 저장된다.
- sayHello() 메서드의 바이트코드도 메서드 영역에 저장된다.
*static이 붙은 정적 변수에 접근라혀면 '클래스명 + .(dot) + 변수명'으로 접근하면 된다.
메서드 영역의 특징:
- 프로그램이 종료될 때까지 메모리에 유지된다.
- 모든 쓰레드가 공유하는 영역이다.
- 객체가 생성될 때, 인스턴스 변수에는 힙 메모리가 할당되지만, 메서드에 대한 새로운 메모리 할당은 없다. 메서드는 메서드 영역에서 공통으로 관리되고 실행된다.
2. 스택(Stack) 영역
스택 영역은 각 쓰레드마다 별도로 할당되는 메모리 공간으로, 메서드 호출과 지역변수(매개변수 포함)를 관리한다. 메서드가 호출될 때마다 프레임(Stack Frame)이 생성되고, 메서드 실행이 끝나면 해당 프레임이 제거된다.
- 지역 변수: 메서드 내부에서 선언된 변수는 스택 영역에 저장된다.
- 메서드 호출 시 생성되는 데이터: 각 메서드 호출 시 생성되는 매개변수, 반환 주소, 임시 데이터 등이 저장된다.
- LIFO 구조: 스택 영역은 후입선출(Last In First Out, LIFO) 구조로, 가장 나중에 호출된 메서드가 먼저 종료된다.
public class Example { public void methodA() { int x = 10; // x는 스택 영역에 저장 methodB(); } public void methodB() { int y = 20; // y는 스택 영역에 저장 } }
- methodA()가 호출되면 스택 프레임이 생성되고, x 변수는 스택에 저장
- methodB()가 호출되면 새로운 스택 프레임이 생성되고, y 변수는 스택에 저장
- methodB()가 종료되면 해당 스택 프레임이 제거되고, 다시 methodA()의 스택 프레임으로 돌아온다.
스택 영역의 특징:
- 메서드의 실행 흐름을 관리한다.
- 스택 영역에 저장된 데이터는 메서드 호출이 끝나면 자동으로 소멸된다.
- 쓰레드별로 독립적인 영역입니다. 각 쓰레드는 자신의 스택을 가지고, 서로 공유하지 않는다.
3. 힙(Heap) 영역
힙 영역은 JVM이 동적으로 생성한 객체(인스턴스)를 저장하는 공간이다. 자바에서 new 키워드를 통해 생성된 객체는 모두 힙 영역에 저장되며, 객체의 실제 데이터(필드 값 등)가 힙에 존재한다.
- 동적 메모리 할당: 힙 영역은 런타임 중에 동적으로 할당된 객체를 저장한다.
- 참조 변수: 객체를 참조하는 참조 변수는 스택 영역에 저장되며, 그 변수가 가리키는 실제 객체는 힙 영역에 저장된다.
- 가비지 컬렉션: 더 이상 사용되지 않는 객체는 가비지 컬렉터에 의해 제거된다.
public class Person { String name; public Person(String name) { this.name = name; } } public class Main { public static void main(String[] args) { Person person = new Person("Alice"); // 힙 영역에 Person 객체 생성 } }
- new Person("Alice")를 호출하면, Person 객체는 힙 영역에 저장됩니다.
- person 변수는 스택 영역에 저장되지만, 이는 힙에 있는 Person 객체를 참조하는 변수입니다.
힙 영역의 특징:
- 힙에 저장된 객체는 명시적으로 삭제되지 않고, 더 이상 참조되지 않을 때 가비지 컬렉션에 의해 자동으로 정리됩니다.
- 모든 쓰레드가 공유하는 영역입니다.
- 큰 객체나 많은 메모리를 요구하는 데이터는 주로 힙 영역에 저장됩니다.
자바 메모리 구조 간 상호작용
- 스택에서 생성된 참조 변수는 힙에 있는 객체를 가리킵니다.
- 메서드 영역에는 클래스와 정적 멤버 정보가 저장되어 있으며, 이 정보는 모든 쓰레드에서 공유됩니다.
- 힙에 있는 객체는 참조 변수가 더 이상 없으면, 가비지 컬렉션에 의해 메모리에서 해제됩니다.
자바 메모리 구조 요약
- 메서드 영역: 클래스 메타데이터, 정적 변수, 상수 및 메서드 코드 저장.
- 스택 영역: 메서드 호출 시 필요한 지역 변수, 매개변수, 반환 값 등이 저장되며, 각 쓰레드별로 독립적.
- 힙 영역: 런타임 시 동적으로 생성된 객체가 저장되며, 가비지 컬렉션에 의해 관리됨.
'JAVA > 개념 - 김영한 강의' 카테고리의 다른 글
상속(Inheritance), @Override, super (0) 2024.09.27 클래스 메서드, 인스턴스 메서드 (1) 2024.09.17 접근제어자 / 캡슐화 (0) 2024.08.30 생성자 -오버로딩(Overloading)과 this() + 오버라이딩(Overriding) (0) 2024.08.25 생성자 (0) 2024.08.24