취업 준비를 하며 복습한다는 마음으로, 이것을 보는 누군가에게 도움이 되었으면 하는 마음으로 Java-Tutoral을 작성해 봅니다. 입문서와 순서가 잘못되었을 수 있고, 제가 아는 정보가 틀렸을 수 있습니다. 이 글에대한 잘못된 정보나, 오탈자 등 수정해야 할 항목 혹은 추가해야 할 항목은 댓글로 알려주시면 감사하겠습니다.
"1. Java 자료형"의 다음에 작성하는 포스팅이지만, 작성하고 나니 이런 생각이 들었다.
나보다 훨씬 대단한 사람들이 만든 언어이니, 아래 내용을 알고 난다면, 조금이라도 더 좋은 프로그래밍을 할 수 있을 것이다!
이런 이유로 자바의 탄생과정, 철학 등 깊지 않게 살펴보려 한다.
1. Java의 탄생
자바(영어:Java,문화어:쟈바)는썬 마이크로시스템즈의제임스 고슬링(James Gosling)과 다른 연구원들이 개발한 객체 지향적프로그래밍 언어이다.1991년그린 프로젝트(Green Project)라는 이름으로 시작해1995년에 발표했다. 처음에는 가전제품 내에 탑재해 동작하는 프로그램을 위해 개발했지만, 현재웹 애플리케이션개발에 가장 많이 사용하는 언어 가운데 하나이고, 모바일 기기용 소프트웨어 개발에도 널리 사용하고 있다. 현재 버전 10까지 출시했다.
자바의 개발자들은유닉스기반의 배경을 가지고 있었기 때문에 문법적인 특성은파스칼이 아닌 C++의 조상인 C 언어와 비슷하다. [1] 자바를 다른 컴파일 언어와 구분 짓는 가장 큰 특징은 컴파일된 코드가플랫폼 독립적이라는 점이다. 자바 컴파일러는 자바 언어로 작성된 프로그램을바이트코드라는 특수한 바이너리 형태로 변환한다. 바이트코드를 실행하기 위해서는 JVM(자바 가상 머신,Java Virtual Machine)이라는 특수한 가상 머신이 필요한데, 이 가상 머신은 자바 바이트코드를 어느 플랫폼에서나 동일한 형태로 실행시킨다. 때문에 자바로 개발된 프로그램은CPU나운영 체제의 종류에 관계없이 JVM을 설치할 수 있는 시스템에서는 어디서나 실행할 수 있으며, 이 점이웹 애플리케이션의 특성과 맞아떨어져 폭발적인 인기를 끌게 되었다.
자바는 초기 설계부터 객체 지향 언어(객체 지향 프로그래밍)로 설계되었다.C가C++로 진화한 것과는 차이가 있다. 그리고 같은 코드로 어떤마이크로프로세서에서나 실행되기를 원했다. 따라서 자바만의 실행 코드인바이트코드라는 중간 코드를컴파일러에 의해 생성한다. 그리고자바 가상 머신(JVM)에 의해 해석되어 실행된다. 따라서 C/C++ 코드로 작성되어 생성된 코드보다 일대일 상황이면 실행 속도가 느리다. 그러나 장점은 같은 코드로 다양한 플랫폼이나 운영 체제에서 실행될 수 있다는 점이다.
2.1. KEY POINT
핵심 목표 5가지
바이트코드
JVM
JVM으로 인해 Java는 하나의 코드로 다양한 플랫폼이나 운영 체제를 지원한다.
3. 자바의 특징
이식성이 높은 언어이다. '이식성이 높다'는 말은 '다양한 플랫폼과, 다양한 운영 체제를 지원한다'와 같다. Java는 JVM(Java Virtual Machine)위에서 작동하기 때문에 운영체제 종류와 상관없다.
일반 프로그램의 경우, 프로그램 -> 운영체제 -> 하드웨어 로 작동한다. 하지만 Java의 경우 프로그램 -> JVM -> 운영체제 -> 하드웨어 로 작동한다.
프로그램과 운영체제 사이에 JVM이 존재한다.
위의 차이로 일반 프로그램은 운영체제의 종류에 따라 데이터 타입의 크기가 달라지기도 하지만, Java의 경우는 크기 자체를 언어에서 직접 고정해서 사용한다.
객체지향언어(OOP)이다. Object Oriented Programming
Java는 OOP방식의 개발용 언어로 설계된 언어이다. 객체지향은 나중에 포스팅 할 '클래스'파트에서 후술하겠다.
함수적 스타일 코딩을 지원한다. 함수적 스타일 코딩은 프로그래밍의 패러다임 중 '선언형 프로그래밍'에 속한다. 순수 함수를 조합하고, 소프트웨어를 만드는 방식인데, 다음의 개념들이 필요하다.
1급 객체 (First Class Object)
고차 함수 (High-Order Function)
불변성 (Immutability)
메모리를 자동으로 관리한다. Java는 다른 언어들과는 다르게 운영체제에 직접적으로 접근하지 않는다. 대신 JVM을 통해 간접적으로 운영체제에 접근하는데, 이런 이유로 JVM을 통해 자동으로 메모리 관리가 가능하다. JVM의 특징 중 하나는 Garbage Collection (GC) 인데, 이 특징이 malloc(), free()를 통해 메모리를 통제한다.
다양한 애플리케이션을 개발할 수 있다. Java는 다양한 오픈소스 라이브러리와 다양한 플랫폼을 제공한다. 이 말은 콘솔프로그램, UI, 서버, 모바일 앱 등 다양한 애플리케이션을 개발할 수 있다는 얘기다.
그렇다면 Java의 대표적인 개발도구를 알아보자.
Java Platform, Standard Edtion (Java SE)
데스크톱 및 서버, 최근의 고사양 임베디드 시스템을 위한 표준 자바 플랫폼이다.
표준적인 컴퓨팅 환경을 지원하기 위해 JVM 규격 및 API 집합을 포함한다.
자바의 여러 플랫폼의 기반이 된다.
Java Platform, Enterprise Editon (Java EE)
자바를 이용한 서버측 개발을 위한 플랫폼이다.
Java SE에 웹 애플리케이션 서버에서 동작하는 장애복구 및 분산멀티티어를 추가한 플랫폼이다.
이 플랫폼을 사용하여 제품으로 구현한 것을 웹 애플리케이션 또는 WAS(Web Application Server)라 한다.
Java Platform, Micro Edition (Java ME 혹은 J2ME)
제한된 자원을 가진 휴대전화, PDA, 셋톱박스 등에서 Java를 지원하기 위해 만들어졌다.
멀티스레드를 쉽게 구현할 수 있다. 단순 해석으로도 여러개의 스레드를 사용하는 방식이다. 병렬처리 라고도 한다. 운영체제마다 멀티스레드를 지원하는 API는 다르다. 하지만 여기서 JVM의 장점이 또 나타나게 된다. 1번 특징에 Java는 JVM 위에서 작동한다 서술했는데, JVM은 운영체제 위에서 작동한다. 따라서 Java는 운영체제마다 다른 API를 사용하는것이 아닌 Java자체의 멀티스레드 API를 이용한다. 위의 이유들로 Java는 일관된 생성 및 관리가 가능하다.
동적 로딩(Dynamic Loading)을 지원한다 만약 프로그램에 탑재 된 클래스가 1억개 이상이고, 정작 사용되는 클래스가 한개 뿐 이라면, 모든 클래스를 가져와 로딩한다면 시간적, 자원적 효율성이 엄청 떨어지게될 것이다.
자바 프로그램은 한개 이상의 클래스들의 조합으로 실행된다. 하지만 Java는 동적 로딩을 지원해, 실행시 모든 클래스가 로딩되는것이 아닌 필요한 시점에 클래스를 로딩하여 사용한다.
장점 : 큰 프로그램을 작은 메모리에서 실행이 가능하다는것이다. 단점 : 프로그램의 실행 속도가 느려질 수 있다. (static 키워드를 사용하면 어느정도 해소가 가능하다. 정적 로딩처럼 메모리에 바로 올라가기 때문이다.)
오픈소스 라이브러리가 풍부하다. Java는 오픈소스 언어이다. 이 특징으로 오픈소스 라이브러리가 엄청 많다! 이 특징을 잘 살린다면, 안정성이 높은 애플리케이션을 개발하는데 시간이 많이 절약될 것이다.
속도가 느리다. 개인적인 생각으로 이 특징은 아니 이 문제점은 현재는 없다고 봐도 괜찮을것 같다. 예전부터 속도가 느리다고 한 이유는 JVM이 원인이었다. 다른 언어들이 컴파일 단계에서 완전한 기계어로 만들어진다면, Java는 중간 단계인 바이트 코드를 거쳐가서 시간이 더 걸릴수 밖에 없었다. 하지만 현재는 JIT 컴파일러 같은 기술이 적용됨에 따라 JVM의 성능이 향상되었고, 속도의 격차가 많이 줄었다.
예외처리가 불편하다. C++에서 Java로 넘어왔을때 정말 어색한느낌을 준 원인 중 하나이다. Java는 다른 언어들과는 다르게 Exception을 개발자가 직접 선언해 처리해야 한다. Java입문서에서도 중요하게 다뤄진다. 이 예외처리에 대한 내용은 '예외처리'파트에서 후술하겠다.
4. JVM (Java Virtual Machine)
JVM은 Java프로그램의 실행을 위해 물리적 머신과 유사한 머신을 소프트웨어로 구현한 것이다. JRE (Java Runtime Environment)에 포함되어 있다.
Java의 클래스는 javac 컴파일러를 거쳐 바이트코드로 변환되며, 이 바이트코드는 JRE에 들어있는 Java classloader에 의해 JVM으로 적재된다. JVM은 적재된 바이트코드를 JIT 컴파일 방식으로 실행한다.
4.1 JVM의 특징
다양한 플랫폼, 다양한 운영체제를 지원한다. (한 번 작성해, 어디서나 실행한다.)
프로그램 메모리를 관리하고 최적화 한다.
Java가 아닌 다른 언어들도 사용이 가능하다 (ex : Kotlin, Scala, Groovy 등)
.NET Framework와 함께 가상머신 언어 시장을 사실상 양분하고 있다.
1995년 자바가 처음 공개 되었을때, 모든 언어는 특정 운영체제에 맞게 작성되었고, 메모리 관리는 개발자가 직접 관리했었다. 하지만 JVM은 이 관념을 깨버렸다!
4.2 Garbage Collection (GC)
JVM의 특징이지만 중요하다 생각되어 따로 다루려 소제목을 붙여줬다. JVM은 Garbage Collection을 수행하여, 말 그대로 쓰레기를 자동 수집하기 시작한다. (쓰레기 = 쓰이지 않는 메모리) 존 매카시가 1959년에 LISP의 메모리 관리를 위해 처음 만들었다 알려져있다.
4.2.1 작동 방식에 따른 분류
추적 기반 쓰레기 수집 (Tracing Garbage Collection) 흔히 사용되는 쓰레기 수집 기법인데, 그래서 보통 쓰레기 수집이라 언급되면, 이 방식을 말한다.
프로그램을 실행하다 특정 타이밍에 root부터 현재 할당된 모든 메모리를 조사하여, 그것이 현재 접근 가능한지, 불가능한지 분류한 뒤, 접근이 불가능한 메모리를 쓰레기라 간주하여 해제시키는 방식이다.
실시간으로 빠르게 동작해야 하는 프로그램에서 뚝뚝 끊기는 것이 큰 단점이다.
점진적 쓰레기 수집 (Incremental Garbage Collection) 점진적 쓰레기 수집은 마킹과 해제를 한번에 하는것이 아닌, 여러번 수행하는 방식을 말한다.
이 방식은 추적 기반 쓰레기 수집에 비해 싸이클 당 걸리는 시간이 더 오래걸리지만, 한번 GC를 수행할 때 프로그램이 정지하는 시간은 줄일 수 있다.
세대별 쓰레기 수집 위 두 방법들이 제시되던 중, 객체에 메모리를 할당해서 더 안 쓰는 쓰레기가 될 때까지 걸리는 시간을 추적하면, 대부분의 객체는 잠깐 쓰고 버려지며, 반대로 오래 살아남아서 쓰이는 경우는 그렇게 많지 않다는 경향을 발견했다.
따라서 위 경향에 맞춰 잠깐 쓰이고 버려지는 객체를 상대적으로 크기가 작은 New 영역에 할당하고, New 영역에서 기준 시간 이상으로 오래 살아남은 객체가 있다면 Old 영역으로 이동시켜, '세대' 구분을 한다. 대부분의 쓰레기는 New 영역에서 발생하므로, 필요한 메모리를 비교적 짧은 시간 안에 확보할 수 있다.