자꾸 안드로이드 스튜디오에서 heap size 에 대해서 초과되었다고 경고 메시지를 주고 있다...
뭐지 ??

근데 언뜻 찾아보니 인스턴스 변수들의 사용량이 매우 커서 힙사이즈가 초과되었다는 얘기를 스택오버플로우에서 본적이 있다.
그래서 이참에 인스턴스 / 지역변수 에 대해 차이점을 자세히 알고 싶었다. 완전히 몰랐던건 아니지만 그렇다고해서 자세하게 안것도 아니다.
알고는 있었지만 비스무리하게 알고 있어서 좀더 명확히 하고 싶었다..
1. 지역 변수와 인스턴스 변수의 차이
첫번째 예시
protected void recyclerview() {
CommunityRVAdapter adapter
= getAdapter(AdapterInterface.AdapterType.COMMUNITY, CommunityRVAdapter.class);
adapter.setEventInterface(this);
binding.communityRV.setAdapter(adapter);
getDatas();
}
우선 위와같은 코드가 있다고 해보자. 이건 내가 사용해왔던 코드 중 하나를 발췌해왔다.
내가 차근차근 하나씩 알아본걸 정리해서 알려주겠다.
- 설명: adapter는 recyclerview 메서드 내에서만 사용되는 지역 변수
- 장점:
- 메서드가 종료되면 adapter는 메모리에서 해제.
- 메서드 내부에서만 사용되기 때문에, 메서드의 다른 부분에서 adapter의 상태를 변경할 수 없음.
- 단점:
- 메서드 외부에서 adapter를 참조하거나 수정할 수 없음.
- 메서드 내에서 adapter가 필요할 때마다 getAdapter 메서드를 호출해야 함.
두 번째 예시
CommunityRVAdapter adapter;
protected void recyclerview() {
adapter = getAdapter(AdapterInterface.AdapterType.COMMUNITY, CommunityRVAdapter.class);
adapter.setEventInterface(this);
binding.communityRV.setAdapter(adapter);
getDatas();
}
- 설명: adapter는 클래스의 인스턴스 변수로 선언되어 있으며, recyclerview 메서드 내에서 초기화됨.
- 장점:
- 클래스의 다른 메서드에서도 adapter를 참조하거나 사용할 수 있음.
- adapter가 클래스 인스턴스의 상태로 유지되므로, 클래스의 다른 메서드에서 adapter의 상태를 참조하거나 수정할 수 있음.
- 단점:
- 클래스의 생명주기 동안 adapter가 메모리에 유지됨.
- adapter의 상태가 클래스의 다른 메서드에서 변경될 수 있어, 클래스의 동작이 복잡해질 수 있음.
2. 요약 결과
- 지역 변수
(" 첫 번째 예시 ")는 메서드 내에서만 사용되며 메서드 종료 시 메모리에서 해제됨.
메서드가 호출될 때마다 새로 생성되므로, 메서드 외부에서 상태를 유지할 필요가 없는 경우 적합.
- 인스턴스 변수
(" 두 번째 예시 ")는 클래스의 생명주기 동안 유지되며, 클래스의 다른 메서드에서 접근할 수 있음.
adapter`의 상태를 클래스 전체에서 참조하거나 수정할 필요가 있는 경우 적합.
어떤 방식을 선택할지는 adapter의 사용 용도와 필요에 따라 달라질 수 있다. adapter의 상태를 클래스의 다른 메서드에서 참조해야 한다면 인스턴스 변수로 선언하는 것이 좋은 부분이지만 반면, adapter가 메서드 내에서만 사용되고 다른 메서드와 독립적이라면 지역 변수로 사용하는 것이 좋다. 하지만 여기에서 가장 중요한 부분은 인스턴스 변수에 참조하고 있는 adapter 의 코드 내용이나 성능적인 부분들이 메모리를 많이 차지한다면 여기에서 비로소 Heap Size 경고사이즈가 나오는 것같다.
많은 메모리를 담아두고 있는 인스턴스 변수를 각 Activity 마다 사용하여 가지고 있다면, 이는 안드로이드 스튜디오에서 할당된 Heap Size 를 초과할 수 밖에 없는 셈이다.
그래서 결국
메서드 내에서 인스턴스 변수를 사용하지 않는다면, static을 붙이는 것을 고려한다
메서드의 작업내용 중에서 인스턴스 변수를 필요로 하지 않는다면 static을 붙이는 것이 좋다.
메서드 호출시간이 짧아지므로 성능이 향상된다.
static을 안 붙인 메서드(인스턴스 메서드)는 실행 시 호출되어야할 메서드를 찾는 과정이 추가적으로 필요하기 때문에
시간이 더 걸리는 부분이 있다. 그래서 static 을 미리 선언하여 로딩시에 이미 인식되어질 수 있게 작업해 놓으면 성능상 빠른 성능을 낼 수 있고 최적화 하는 부분에서도 당연 좋은 기능을 낼 수 있다.
그럼 static 인 전역 변수 ( 클래스 변수 ) 란 과연 무엇인가?

클래스 변수(Static 멤버)
- 클래스 내에 Static 키워드로 선언된 변수
- 처음 JVM이 실행되어 클래스가 메모리에 올라갈 때 ~ 프로그램이 종료될 때까지 유지
- 클래스가 여러 번 생성되어도 Static 변수는 처음 딱 한 번만 생성됨
- 동일한 클래스의 모든 객체들에 의해서 공유됨
그래서 static 을 많이 쓴다 해도 단점이 존재한다. 메모리 누수에 취약하다는 부분이 있다.
물론 Instance 변수에도 적용되지만 static 에 대해서는 앱 성능에도 큰 영향을 끼치기 때문에 특별히 메모리 누수에 각별을 주의해야 한다.
인스턴스 변수(Non-static 멤버)
- 클래스 내에 선언된 변수
- 객체 생성 시마다 매번 새로운 변수가 생성됨
- 클래스 변수와 달리 공유되지 않음
이 부분은 참고로 그냥 적어놓았다
앞으로 잘 공부해보자 !!!!

그럼 조금 더 요약정리 해보자 !!!
요약정리
✅ Java 변수의 종류
Java에서 변수는 크게 4가지로 분류할 수 있어.
변수 종류선언 위치메모리 영역초기화 여부접근 범위
인스턴스 변수 | 클래스 내부 (객체 멤버) | Heap | 자동 초기화 | 객체 내부 |
클래스 변수 (static 변수) | static 키워드 사용 | Method Area | 자동 초기화 | 클래스 내부 (모든 객체 공유) |
지역 변수 | 메서드 또는 블록 내부 | Stack | 수동 초기화 필요 | 선언된 블록 내 |
매개변수 | 메서드의 파라미터 | Stack | 호출될 때 값 전달 | 메서드 내부 |
1️⃣ 인스턴스 변수 (Instance Variable)
클래스 내부에서 선언되며, 객체가 생성될 때 메모리에 할당되는 변수
📌 특징
- static 없이 선언한 클래스의 멤버 변수
- Heap 메모리에 저장됨
- 객체가 생성될 때 자동 초기화됨
- 각 객체마다 별도의 값을 가짐
📌 예제
class Person {
String name; // 인스턴스 변수 (자동 초기화: null)
int age; // 인스턴스 변수 (자동 초기화: 0)
void display() {
System.out.println("이름: " + name + ", 나이: " + age);
}
}
public class Main {
public static void main(String[] args) {
Person p1 = new Person();
p1.name = "Alice";
p1.age = 25;
Person p2 = new Person(); // 별도의 인스턴스 변수 생성
p2.name = "Bob";
p2.age = 30;
p1.display(); // 이름: Alice, 나이: 25
p2.display(); // 이름: Bob, 나이: 30
}
}
2️⃣ 클래스 변수 (Static Variable)
클래스에 속하며, 모든 객체가 공유하는 변수
📌 특징
- static 키워드를 붙여 선언
- Method Area에 저장 (프로그램 종료 시까지 유지)
- 객체를 생성하지 않아도 접근 가능
- 모든 객체가 공유하는 값
📌 예제
class Counter {
static int count = 0; // 클래스 변수 (자동 초기화: 0)
Counter() {
count++;
}
void display() {
System.out.println("현재 개수: " + count);
}
}
public class Main {
public static void main(String[] args) {
Counter c1 = new Counter();
Counter c2 = new Counter();
c1.display(); // 현재 개수: 2
c2.display(); // 현재 개수: 2
}
}
- count 변수는 모든 객체가 공유함.
- 객체를 생성할 때마다 증가하지만, 모든 인스턴스에서 같은 값을 참조.
3️⃣ 지역 변수 (Local Variable)
메서드나 블록 내부에서 선언되고, 해당 블록 내에서만 사용 가능한 변수
📌 특징
- Stack 메모리에 저장됨
- 선언된 블록({}) 내부에서만 사용 가능
- 자동 초기화되지 않음 → 사용 전 반드시 초기화해야 함
- 메서드가 종료되면 메모리에서 사라짐
📌 예제
public class Main {
void printNumber() {
int num = 10; // 지역 변수 (자동 초기화 X → 직접 초기화 필요)
System.out.println("Number: " + num);
}
public static void main(String[] args) {
Main obj = new Main();
obj.printNumber();
// System.out.println(num); // 오류! (num은 지역 변수라 접근 불가)
}
}
- num은 printNumber() 메서드 안에서만 사용 가능.
- 메서드가 끝나면 num은 메모리에서 사라짐.
4️⃣ 매개변수 (Parameter Variable)
메서드 호출 시 값을 전달받아 사용하는 변수
📌 특징
- 메서드 선언부에서 정의됨
- 메서드가 호출될 때 값을 넘겨받아 사용
- Stack 메모리에 저장됨
- 메서드 실행이 끝나면 사라짐
📌 예제
public class Main {
void greet(String name) { // 매개변수 name
System.out.println("Hello, " + name);
}
public static void main(String[] args) {
Main obj = new Main();
obj.greet("Alice"); // "Hello, Alice"
obj.greet("Bob"); // "Hello, Bob"
}
}
- greet(String name)의 name은 메서드 호출 시 전달받은 값을 저장.
- 메서드가 실행될 때만 존재하고, 끝나면 메모리에서 제거됨.
✅ 변수 종류별 차이점 정리
변수 종류선언 위치메모리 영역초기화 여부특징
인스턴스 변수 | 클래스 내부 | Heap | 자동 초기화 | 객체마다 별도 관리 |
클래스 변수 (static 변수) | static 키워드 사용 | Method Area | 자동 초기화 | 모든 객체가 공유 |
지역 변수 | 메서드/블록 내부 | Stack | 수동 초기화 필요 | 선언된 블록 내에서만 사용 가능 |
매개변수 | 메서드 파라미터 | Stack | 호출 시 값 전달 | 메서드 실행 중에만 존재 |
✅ 마무리
- 인스턴스 변수 → 객체별 개별 값
- 클래스 변수 (static 변수) → 모든 객체가 공유하는 값
- 지역 변수 → 선언된 블록 내에서만 사용 가능 (자동 초기화 X)
- 매개변수 → 메서드 호출 시 전달된 값
'개발 > Java' 카테고리의 다른 글
Java_ google social Login (1) | 2024.10.18 |
---|---|
Java_ buildType 활용하여 debug, release 구분하기 (0) | 2024.10.02 |
Java & Swift _ runOnUiThread , view.post , handler, DispatchQueue.... 의 차이 (0) | 2024.09.12 |
Java_ Rxjava blockingGet , subscribe ... (0) | 2024.08.25 |
Java_ Lazy Singleton (0) | 2024.08.25 |