[JAVA] 2주차 정리: 컴파일러, JVM, 키워드, 스택, 힙 세그먼트
1. Java 프로그램 구조
-
크게 package, import, class로 이루어짐
- package: 클래스를 묶어줌
- import: 사용하고자 하는 다른 클래스가 포함된 패키지를 가져옴
- class: 함수와 변수로 구성된 객체를 만드는 틀
✏️Complier 컴파일러
: 고급 언어로 작성된 프로그램 전체를 목적 프로그램으로 번역한 후, 링킹 작업을 통해 컴퓨터에서 실행 가능한 실행 프로그램을 생성
- 이때 원래의 소스를 원시 코드, 바뀐 코드를 목적 코드(Object Code)라고 함
- 번역 실행 과정을 거쳐야 하기 때문에 번역 과정이 번거롭고 번역 시간이 오래 걸림, 한번 번역한 후에는 다시 번역하지 않으므로 실행 속도가 빠름
- 컴파일러를 사용하는 언어: C, Java 등
✏️Interpreter 인터프리터
: 고급 언어로 작성된 프로그램을 한 줄 단위로 받아들여 번역하고, 번역과 동시에 프로그램을 한 줄 단위로 즉시 실행시킴
- 줄 단위로 번역, 실행되기 떄문에 시분할 시스템에 유용하며 원시 프로그램의 변화에 대한 반응이 빠름
- 번역 속도는 빠르지만 프로그램 실행 시 매번 번역해야 하므로 실행 속도 느림.
- 인터프리터를 사용하는 언어: Python, BASIC 등
✏️Java Virtual Machine (JVM) 자바 가상 머신
: 자바 프로그램을 읽어들여 자바 API와 함께 실행시키는 프로그램
- 즉, 한번 만들어놓은 자바 프로그램이 어느 기기, 운영체제 상에서도 실행될 수 있게 해줌 (중개자 역할)
- 프로그램 메모리를 관리하고 최적화함(Garbage collection)
-
스택 기반의 가상머신
- 실행과정
- 프로그램이 실행되면 JVM은 운영체제로부터 프로그램에 필요한 메모리를 할당받음
- 자바 컴파일러(javac)가 자바 소스코드(.java)를 읽어들여 자바 바이트코드로 변환시킴(.class)
- 클래스 로더를 통해 JVM으로 클래스파일을 로딩하고 Excution engine을 통해 해석
- 해석된 바이트코드는 Runtime Data Areas에 배치되어 실질적 수행이 이루어짐
*이 과정속에서 필요에 따라 스레드 synchronization과 같은 관리작업을 수행함
*Excution engine 실행엔진: 클래스를 실행시킴, 이때 인터프리터를 통해 실행엔진은 한 줄씩
명령어 단위로 읽고 실행하는데 속도가 느리다는 단점을 보완하기 위해 JIT컴파일러를 도입함. 즉, 자바는 컴파일과 인터프리터 방식을 병행하는 언어임.
2. Java 식별자
- 모든 언어는 각자 식별자가 있음
- 클래스이름, 메소드이름, 변수이름
- 변수
- member field (=member variable) 멤버변수
- local variable 지역변수
-
규칙
- 문자와 숫자의 연속, 문자로 시작해야 함 - ‘_’와 ‘$’로 시작 가능 - 키워드 사용 불가 (Ex true, null) - 클래스 이름은 대문자, 함수와 변수 이름은 소문자로 시작 (자바는 대소문자 구분이 가능) - 길이 제한 없음 - 클래스, 메소드, 변수 이름 동일시X (컴파일 에러는 발생하지 않지만 개발자에게 혼돈 야기) - 한글사용 가능하나 오류 가능성이 있으므로 사용X
- 예시
➢ User Name : 띄어쓰기 불가, 문자와 숫자 연속해야 함 ➢ 7userName : 문자로 시작해야 함 ➢ true : 키워드 사용 불가 ➢ #argument : ‘_’와 ‘$’로 시작 가능
3. Java 키워드
-
예외처리 관련 키워드
- try, catch: try문 실행, 예외 발생 시 catch로 넘어가 예외처리 - finally: try-catch 예외처리 마지막에 무조건 수행되는 문장 - throw: 특정 상황에 예외를 발생시킴, try 함수를 시행할 때 영향을 줌 - throws: 예외를 정의하고 상위 메소드로 처리, catch에서 발생 될 수 있는 예외
-
자바에만 있는 독특한 키워드
- native, violatile, transient: 데이터에 대한 특징 - synchronized: 동기화와 관련
-
객체지향 관련 키워드 – Class 중심
- class: 객체지향의 핵심, 바디가 있는 것, 메소드와 변수를 캡슐화시켜주는 기능 - interface: 클래스와 동등한 개념, 함수 이름만 정의해 놓은 것 - package: 클래스를 묶어줌 - import: 클래스 내에서 다른 클래스를 쓸 때 사용, 다른 사람이 만든 패키지를 가져옴 - extends: 상속 관련 키워드, 클래스 상속, 부모의 메소드, 변수를 그대로 사용 가능 - implements: 상속 관련 키워드, interface 구현, 부모의 메소드를 자식에서 오버라이딩하여 사용 - abstract: 추상적 메소드로 구현 - new: 객체를 만들 때 사용 - this: 자기 자신을 가리킬 때 사용 - super: 부모의 클래스를 사용하고 싶을 때 사용 - instanceof: 클래스 내에서 객체변수가 어떤 클래스에서 나왔는지 확인할 때 사용 - private: 함수, 클래스에 다 존재, 다른 클래스에 공유하지 않음 - protected: 패키지 내에 있는 클래스에만 허용함 - public: 클래스를 공유함 - static: 상속과 연결되어 클래스에 속해있는 메소드와 변수를 상속하지만 바꿀 수 없음 - final: 상속시키지 않음
✏️Refernce Type 참조형 – 키워드 this, super
- 자바의 기본형을 제외한 모든 타입 (class, interface, array, enum)
- 기본적으로 java.lang.Object 클래스를 상속하는 모든 클래스를 말함
- heap 영역의 동적 메모리 할당(dynamic memory allocation)을 지원함
-
즉, heap 영역에 필요한 데이터를 확보하고, 확보된 영역을 참조하는 것이 참조형
• 특징
- 빈 객체를 의미하는 Null이 존재
- class에서 new로 객체를 생성할 때, 혹은 array 공간을 생성할 때 힙 영역의 reference 공간이 만들어짐
-
메인메모리 = 실행코드(code segment) + 힙 영역(heap area, data segment) + 스택
-
실제 객체는 Heap Area에 저장되며 참조형 변수는 Stack 영역에 실제 객체들의 주소를 저장함. 객체를 사용할 때마다 참조 변수에 저장된 객체의 주소를 불러와 사용
- CPU는 메모리에 접근해서 데이터를 가져옴
✏️Instance 인스턴스 – 키워드 new
- 객체(Object): 모든 인스턴스를 대표하는 포괄적 의미, 클래스의 인스턴스
- 클래스(Class): 객체를 만들어 내기 위한 설계도
-
인스턴스(Instance): 설계도를 바탕으로 구현된 구체적인 실체
: 어떤 클래스로부터 만들어진 객체로 어떤 클래스에서 만들어졌는지 강조• 특징
- 인스턴스는 객체에 포함된다고 볼 수 있음
- 추상적 개념(또는 명세)과 구체적인 객체 사이 관계에 초점을 맞출 경우 사용됨
- 객체가 메모리에 할당되어 실제 사용될 때 “instance”라고 부름
- 인스턴스는 함수와 변수로 구성
- ‘~의 인스턴스’ 형태로 사용
- 클래스에서 new로 객체를 생성함
- 즉, 클래스 타입으로 선언되었을 때 객체라고 부르고, 그 객체가 메모리에 할당되어 실제 사용될 때 인스턴스라고 부름
- 또한, 인스턴스라는 용어는 반드시 클래스와 객체 사이의 관계로 한정지어 사용할 필요X
4. Stack 스택
- 스택 영역(Stack Area): 정적 메모리 할당 및 스레드 실행을 위해 사용되는 영역
- 메소드 내에 정의되는 기본형 변수의 데이터값과 힙 영역에 생성된 객체의 참조 값이 저장됨
- 스레드를 실행하기 위해 사용
- 각 Thread는 자신만의 stack을 가짐
- 메소드 실행이 끝나면 할당되었던 메모리 공간은 반환되어 비워짐
- 힙 영역보다 메모리영역이 작음
- 힙 메모리에 비해 액세스 속도가 빠름
- 스택: 마지막에 들어온 것이 먼저 나가는 LIFO(Last In First Out) 구조를 가진 자료 구조
5. Heap 힙
- 힙 영역(Heap Area) : 메인메모리 중 동적으로 메모리를 확보하는 영역. 프로그램이 실행될 때 데이터를 저장하는 공간
- 보통 new를 통해 생성된 인스턴스 변수가 저장됨
- 메소드 호출이 끝나도 사라지지 않음
- Garbage Collector는 힙 영역에 더이상 참조하지 않는 객체들을 지움
6. Segment 세그먼트
-
세그먼트는 프로그램에 정의된 특정 영역으로 코드, 데이터, 스택으로 알려져 있는 것을 포함
-
세그먼트는 메모리의 거의 어느 곳에나 위치할 수 있음
-
명령어가 세그먼트 레지스터에 세그먼트 주소를 적재할 때, 가장 오른쪽에 위치한 네 개의 0비트가 자동으로 오른쪽으로 이동하면서 제거됨
-
임의 개수의 세그먼트를 정의하는 것이 가능, 특정 세그먼트에 대해 주소를 지정하기 위해서는 적절한 세그먼트 레지스터의 값을 그 주소로 변경하기만 하면 됨
• 코드 세그먼트(code segment) - 실행코드 - 첫번째로 실행 가능한 명령어는 이 세그먼트의 맨 처음에 위치하며, 운영체제는 프로그램 실행을 시작하기 위해 그 위치를 알고 있음. - 코드 세그먼트(CS) 레지스터: 코드 세그먼트의 주소 • 데이터 세그먼트(data segment) - 힙 영역 - 코드에서 정의된 데이터, 상수, 작업 영역 - 데이터 세그먼트(DS) 레지스터: 데이터 세그먼트 주소 • 스택 세그먼트(stack segment) - 프로그램이 임시로 저장할 필요가 있거나, 사용자의 ‘피호출’ 서브루틴이 사용할 데이터와 주소를 포함 - 스택 세그먼트(SS) 레지스터: 스택 세그먼트 주소 • 세그먼트 경계 - 세그먼트 레지스터는 크기가 16비트이며, 세그먼트의 시작 주소를 포함. - 세그먼트 레지스터는 SS, DS, CS, ES(extra segment)가 있으며, 80386과 그 이후 프로세서에서는 FS와 GS 레지스터가 제공됨.