0. 배경
최근 자바 공부를 하면서 문득 궁금해졌습니다.
“Java 클래스 안에는 변수를 몇 개까지 선언할 수 있을까?”
“메서드 안의 지역 변수는 몇 개까지 선언할 수 있을까?”
막연히 ‘메모리가 허락하는 한’이라고 생각했지만 JVM 내부 구조와 한계를 정확히 알고 싶어서 직접 확인해보기로 했습니다.
1. 문법적 제한은 없다
자바 언어 차원에서는 변수를 몇 개까지 선언할지 제한하지 않습니다.
즉 아래처럼 수천 개를 선언해도 문법 오류는 발생하지 않습니다.
public class BigClass {
int a1;
int a2;
int a3;
// ...
int a10000;
}
하지만 JVM에는 “상수 풀(Constant Pool)” 제한이 있습니다.
2. JVM 상수 풀(Constant Pool) 제한
클래스가 컴파일되면 .class 파일에는 다음 정보가 들어갑니다.
- 필드 정보 (field_info)
- 메서드 정보 (method_info)
- 상수 풀(Constant Pool): 문자열, 타입, 메서드 참조 등
상수 풀(Constant Pool)의 크기는 최대 65,535개 항목(= 2¹⁶ - 1) 으로 제한되어 있습니다.
즉, 필드, 메서드, 문자열 리터럴 등 클래스에 포함되는 모든 요소가 이 상수 풀을 공유합니다.
java.lang.ClassFormatError: constant pool count exceeds limit of 65535
너무 많은 변수를 선언하면 ClassFormatError가 발생할 수 있습니다.
3. 실질적 한계: 메모리와 스택 프레임
- 인스턴스 변수 → 힙(Heap)에 저장
- 지역 변수(Local Variable) → 스택(Stack)에 저장
따라서 변수 개수가 많을수록:
- 객체당 힙 메모리 증가
- GC(가비지 컬렉션) 부하 증가
- 생성 시 OutOfMemoryError 발생 가능
정리
| 문법적 제한 | 없음 | Java 문법 수준 |
| 클래스 파일 제한 | 약 65,535개 요소 | JVM Constant Pool |
| 실행 시 메모리 제한 | JVM Heap, OS 메모리 | 물리적 자원 한계 |
4. 그럼 메서드는 제한이 있을까?
이론상 65,535개지만 서드 바이트코드 길이 제한 64KB 때문에 그전에 에러가 터집니다
이유는
- 메서드 내 코드 크기(bytecode length)가 64KB를 넘을 수 없습니다.
(`method_info`의 `code_length`는 16비트 제한)
- 변수를 65,000개 선언하려면 코드가 64KB를 넘기 때문에
실제로는 수백~수천 개 수준에서 이미 컴파일 실패합니다.
JVM Local Variable Table 구조
메서드 호출 시 JVM은 스택 프레임(Stack Frame)을 생성하고 그 안에 변수를 저장합니다.
| Local Variable Table | 메서드 내부 변수 저장 |
| Operand Stack | 계산 중간 결과 저장 |
| Constant Pool Reference | 클래스 상수 풀 참조 |
- 각 변수는 1개 슬롯(slot) 차지 (long, double은 2 슬롯)
- 최대 65,535 슬롯 제한
void test() {
int[] arr = new int[70000]; // 배열은 가능
int a1, a2, a3, ..., a70000; // X 불가능
}
5. 그렇다면 C 언어에서는?
C 언어에서는 클래스라는 개념은 없지만 구조체나 전역 변수를 포함한 클래스 변수(멤버 변수와 유사한 개념)는 문법상 제한이 없습니다.단 객체 크기가 커지면 힙/스택 메모리 한계 때문에 실질적 한계가 존재합니다.
- 지역 변수는 스택 크기가 한계를 결정합니다
- 기본 스택 크기: 1~8MB (OS/컴파일러 설정)
- 스택 초과 시 Stack Overflow 발생
함수(메서드) 개수 제한
- C 언어에서는 함수 선언 개수 자체에 문법적 제한은 없음
- 단 컴파일러와 링커가 처리할 수 있는 심볼 테이블 크기나 객체 코드 크기 한계가 존재
- 즉, 수천~수만 개 함수까지는 대부분 문제 없이 컴파일 가능하지만, 극단적으로 많으면 링커 오류 발생 가능
6.마치며
처음에는 단순히 변수를 몇 개까지 선언할 수 있을까?가 궁금했지만, 조사하면서 자바 JVM의 상수 풀(Constant Pool)과 메서드 구조가 변수 한계와 밀접하게 연관되어 있다는 것을 알게 되었습니다.
덕분에 JVM 내부 구조를 더 잘 이해하게 되었습니다.
'자바' 카테고리의 다른 글
| [JVM 완전정복 #2] 자바 프로그램의 첫 관문 - 클래스로더 (0) | 2025.11.17 |
|---|---|
| JIT 컴파일러와 일반 컴파일러의 차이를 알아보자 (0) | 2025.11.14 |
| [JVM 완전정복 #1] JVM 구성요소 총정리: 가상 머신이 자바 코드를 실행하는 비밀 (0) | 2025.11.11 |
| 프로그래밍 언어의 시작 – 고급어와 저급어의 이해 (0) | 2025.11.04 |
| 객체지향 프로그래밍(Object-Oriented Programming) (1) | 2025.10.28 |