자꾸 안드로이드 스튜디오에서 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_ google social Login (1) | 2024.10.18 |
---|---|
Java_ buildType 활용하여 debug, release 구분하기 (0) | 2024.10.02 |
Java_ runOnUiThread , view.post , handler 의 차이 (0) | 2024.09.12 |
Java_ Rxjava blockingGet , subscribe ... (0) | 2024.08.25 |
Java_ Lazy Singleton (0) | 2024.08.25 |