자바 기초 (01). Java 제대로 공부 해보기
Java 제대로 공부하기 첫번째 포스팅
0. 들어가며
최근 5년만에 자바 관련 프로젝트를 진행중이다, 아래 글과 같이 migration, synchronization 작업을 하고 있는데, Java언어를 Java언어 처럼 짜지 못하는게 너무 아쉬웠다,, 그런상태에서 다른 라이브러리들을 설명하려니 잘 전달이 되지 못했던것 같다. 그래서 주말이 되면 자바를 좀 더 기초부터 심도있게 공부해보면 어떨가 싶어 이 강좌를 적어본다. 기초라 하여 자바과정의 시작부터 하는것은 아니며, 내가 그냥 넘어갔었던 그러한 부분들을 확인해보며 넘어가고자 한다. Quartz에 대한 포스팅은 자바강의를 마치고 좀 더 다루어 보려 한다. ( 도커, git 도 해야될게 많은데,,,)
[열혈강의] 객체 중심 Java 위 강의를 중심으로 포스팅 하였습니다. 강요천강사님은 제가 12년도 대학교 1학년때 비트아카데미에서 수업을 들었던것 같은데 지금들어도 강의 퀄리티가 좋네요
1. Java 프로그래밍 소개
컴파일 언어와 Interpreter 방식의 언어, Java 언어는??
- 컴파일 언어 :
- High level -> CPU 인스트럭션으로 직접 변환은 불가
- 중간에 CPU의 언어로 해석할 수 있는 간접적인 장치를 컴파일러 라고 한다.
- 보통의 경우 컴파일러를 통해서 운영체제와 통신하는 코드를 생성한다.
(.exe 파일등 컴파일러로 변환된 순간 용량이 늘어난다.)
- Interpreter 언어
- 컴파일을 통해서 운영체제와 통신하는 방식의 대안
- 특정한 프로그램이 실행되면서 프로그램에 필요한 로직이나 데이터를 해석
- 해석기의 존재만 있다면 운영체제에 영향을 덜 받을 수 있다는 장점
(ex)인터넷 브라우저도 해석기의 일종이다.
- Java
- Java 언어는 C/C++언어에서 문법적인 내용을 취해서 개발 진입장벽을 낮춘 언어
- C/C++에서 개발자들이 혼란을 가질 만한 부분을 제거하여 메모리의 관리/운영체제에 대한 독립을 이루어냄 ( gc() garbage collector에 모든것을 맡김 )
- 객체지향 패러다임을 처음으로 성공적으로 활용하였다.
- Java Virtual Machine (JVM) 이라는 독특한 장치를 가짐
-
JVM의 컴파일 방식은 조금 독특하다. 위에 컴파일러를 설명했던것과는 다르게 Java Compiler가 .java 파일을 기계어인 .class파일로 만들어주면 이걸 바로 운영체제(OS)와 통신하는것이 아닌 JVM이 해석할수 있는 기계어로 만들어 준다. 이러한 인터프리터방식으로 인해 초반 JAVA는 느리다는 말을 듣게 되었다. 하지만 Interpreter의 장점인 운영체제를 안탄다는 장점으로 인해 큰 성공을 거두게 된다.
- 장점
- 운영체제에 독립적인 실행이 가능
- 개발자가 Low level에 대한 지식이 부족한 상태에서 개발 가능
- 컴파일된 결과물이 가볍다
- 단점인 하드웨의 직접적인 접근이 어렵다 <=> (바이러스를 만들수 없다). = 안정성
- 단점
- 메모리 제어가 어렵다
- 운영체제나 하드웨어에 직접적인 접근이 어렵다.
2. Java 프로그램의 실행과정 이해
C언어 실행순서 & Java 언어 프로그래밍 실행 순서
3. JVM 이해하기
위에서 JVM을 설명하긴했지만 조금만 더 알아보도록 하자
JVM은 Garbage Collector, Class Loader, Execution Engine, Runtime Data Areas(JVM 메모리 영역) 으로 구성되어 있다.
Class Loader : 모든 클래스는 참조되는 순간에 동적으로 JVM에 Link되며 메모리(Class Area)에 로딩이 되는데, 동적 클래스 로딩은 Class Loader을 통해 이루어 진다.
JVM 은 클래스에 대한 정보를 알지 못하기 때문에 그 정보를 알지 못하기 때문에 그 정보를 Class Loader가 Class 파일을 찾아 검사하고 메모리에 저장해두는 것이다.
Execution Engine
- 실행코드를 인스트럭션으로 변환하고 해석해서 실행
- 바이트코드(.class) -> JVM -> 어셈블리 -> CPU
- Execution Engine이란 ByteCode를 실행하는 Runtime Module이다.
- 일반 Interpreter 는 속도가 느리다는 단점이 있지만 아래와 같은 방식으로 보완한다.
- JIT(Just In Time)
- 반복 수행되는 코드를 기존 해석한 내용을 활용하는 방식(성능향상)
- Hotspot
- 성능의 저하를 가져오는 부분을 프로파일링 해서 집중처리
- 처음엔 속도가 느리지만 점점 빨라진다고 한다고 이해
Garbage Collector
- 메모리의 회수를 담당
- 이렇게 한다고 해도 out of memory는 발생하므로 생각하며 잘 짜는 습관이 중요, 지금하는 내 프로젝트에서도 발생했음,,
- Heap 영역에서 동작
- Heap이란 메모리를 동적으로 사용하는 공간
- 사용되지 않는 메모리를 판단해서 자체적으로 삭제하는 매커니즘
- JDK의 major 버전을 결정하는 가장 큰 용니
- System.gc() 를 직접불러 쓰는건 고민해볼문제임 (속도문제)
- ## System.gc ()를 호출하는 것이 왜 나쁜 습관입니까?
메모리영역
-
CLASS(==Static==Method) 영역 사용하는 클래스 파일의 바이트 코드가 로드되는 곳으로 static 변수의 값 그리고 멤버 변수, 메소드 등 클래스에 대한 정보 = metadata가 JVM이 종료될때 까지 유지된다.
이렇게 Class 영역에 바이트 코드가 올라가는 것을 ClassLoading이라고 하며, ClassLoading이 되야 하는 이유는 메소드를 호출하기 위해서는 먼저 그 메소드를 갖고 있는 바이트 코드가 메모리에 로딩되어 있어야 하기 떄문이다. -
STACK 영역 지역변수와 매개변수가 저장되는 곳으로 메소드가 호출되거나 로프문안으로 들어올때 스택영역에 메모리를 할당한다. 지역문 안에서만 임시 할당 되어있다가 지역문이 끝나면 삭제된다.
-
HEAP 영역 기본형 변수를 제외한 참조형 변수들이 가르키는 곳(주소)에 내용이 저장되는 영역. new를 통해 생성된 인스턴스가 저장되는 곳.
예를 들어보자
class A{
int number_1;
int number_2;
}
public static void main(String[] args) {
A sample= new A();
}
이렇게 메인 메소드에서 A의 인스턴스를 생성하게 되면 __Stack영역__에는 지역변수인 sample과 sample의 내용이 저장된 참조값이 저장되고, __Heap영역__에는 sample 안에 있는 인스턴스 변수인 int number_1과 int number_2가 저장된다.
new로 생성된 객체의 내용은 힙영역에 저장되고, 참조형 변수인 sample은 main함수안에 있는 지역변수 이므로 스택영역에 저장된다.
java변수에 대해 궁금하다면 자바[JAVA] 변수 정리 를 확인하면 좋을듯 하다.