[Java] Java란?
2022. 4. 30. 14:18
1. Java의 등장
썬 마이크로시스템즈(Sun Microsystems, Inc)에서 개발하여 1996년 1월에 발표한 객체지향 프로그래밍 언어이다.
자바의 역사는 1991년 제임스 고슬링, 아서 밴 호프를 포함한 썬 엔지니어들이 가전제품에 탑재될 소프트웨어를 만들고자 C++의 장점을 도입하고 단점을 보완한 오크(Oak)라는 언어를 개발한 것에서부터 시작되었다. Oak는 운영체제에 독립적인 장점이 있어 가전제품이나 PDA와 같은 소형기기보다 여러 종류의 운영체제를 사용하는 컴퓨터들이 통신하는 인터넷에 적합하다고 판단되었다. 그래서 Oak를 웹에 적합하게 개발 방향을 바꾸며 이름을 자바(Java)로 변경하였으며, 자바로 개발된 '핫 자바(Hot java)'를 발표하고 1996년 1월에 자바의 정식 버전을 발표했다.
자바라는 이름은 인도네시아 자바섬에서 생산한 커피의 이름에서 따왔으며 자바의 로고는 커피잔이고, 마스코트는 듀크(Duke)이다.
2. Java 특징
2-1) 장점
- 운영체제에 독립적
기존의 언어는 다른 운영체제별로 적용하기 위해 많은 노력이 필요하다.
반면 자바는 각 운영체제에 맞는 자바 가상머신(JVM)만 설치되어 있으면 JVM하고만 통신하기 때문에 운영체제 종류에 상관없이 독립적이다. JVM의 동작 원리는 조금 뒤에 설명하겠다. - 객체지향 언어
자바는 객체를 중심으로 메소드가 데이터에 접근해서 객체의 속성을 조작하는 형태의 언어이며, 객체지향개념의 특징인 상속, 캡슐화, 다형성이 잘 적용된 순수한 객체지향언어라 평가된다. - 가독성
자바의 연산자와 기본 구문은 C++, 객체지향관련 구문은 스몰톡(small talk)이라는 언어에서 장점만 취하고 복잡하고 불필요한 부분은 제거하여 단순화함으로써 배우기 쉽고, 간결하고 이해하기 쉬운 코드를 작성할 수 있도록 하였다. - 자동 메모리 관리
자바는 GC(garbage collector)가 자동적으로 메모리를 관리해주므로 개발자는 메모리를 따로 관리하지 않아도 된다. 이를 통해 개발자는 메모리를 체크하고 반환하는 일을 신경쓰지 않아도 되므로 프로그래밍에 좀 더 집중할 수 있다. - 네트워크와 분산처리 지원
자바는 네트워크 분산처리 환경에서 사용하기 위해 고안된 언어이므로 다양한 네트워크 관련 라이브러리(Java API)를 통해 비교적 짧은 시간에 네트워크 관련 프로그램을 쉽게 개발할 수 있도록 지원한다. - 멀티쓰레드 지원
자바에서 개발되는 멀티쓰레드 프로그램은 운영체제에 상관없이 구현가능하며, 관련된 라이브러리를 제공하므로 구현이 쉽다. 그리고 멀티쓰레드에 대한 스케줄링(scheduling)을 자바 인터프리터가 담당하게 된다. - 동적 로딩(Dynamic Loading) 지원
자바로 작성된 프로그램은 클래스 파일로 구성되어 있는데, 프로그램 실행시에 모든 클래스를 로딩하지는 않고 필요한 시점에 클래스를 로딩하여 사용할 수 있다.
일부 클래스가 변경되어도 전체 어플리케이션을 다시 컴파일하지 않아도 되며, 어플리케이션의 변경사항이 발생해도 비교적 쉽게 처리할 수 있는 유연성을 가진다.
2-2) 단점
- 속도 문제
자바는 C/C++ 같은 네이티브 바이너리 코드를 만드는 언어와 비교했을 때 느린 속도이지만, 다른 고수준 언어들보다 많이 떨어지지는 않는다. 이러한 속도 문제를 해결하기 위해 1.4버전에서 JIT 컴파일 지원이 되어 상당히 개선되었다.
버전에 따라서도 지속적인 업데이트를 통해 속도가 빨라지고 있어 Java 15는 11보다 평균 11%, Java 11은 8보다 평균 16%정도 빠르다. - JVM 로딩 속도 문제
자바는 JVM이 반드시 완벽하게 로딩되어야 하므로, 완전한 이진 코드로 컴파일된 프로그램을 실행하는 것에 비해 초기 실행시간이 오래 걸린다. 콘솔 화면에 "Hello World" 한 문장을 찍기만 하는 프로그램이 실행되는 데에도 쓰레드가 많이 뜨는 것을 볼 수 있다. - JVM 바이트코드 실행 속도 문제
자바는 JVM이 운영체제와 프로그램 사이에 있어, 바이트코드로 된 프로그램을 해석해 각 플랫폼용 기계어에 맞게 번역하여 실행한다. 하지만 다른 네이티브 바이너리 코드를 출력하는 언어에 비해 바이트코드를 해석하는 과정이 추가되어 있으므로 실행속도와 성능에 일부 손실이 발생한다.
이를 해결하기 위해 JIT 컴파일러를 JVM에 내장해 성능을 개선하였지만, 이를 뒷받침하는 메모리가 필요하다. - 가비지 컬렉션에 의한 실행 지연 문제
GC에 의한 메모리 프리징 현상은 끊김없이 동작해야하는 프로그램이 순간적으로 끊기는 현상이 발생하는 것이다.
Java 8부터 기본 GC로 설정된 G1GC는 메모리 누수를 일으키던 메소드 영역의 PermGen Area를 제거하여 static 인스턴스와 리터럴 문자열도 GC의 대상이 되도록 바뀌었으며, 클래스, 메소드, 배열의 메타 정보는 동적 리사이징이 가능한 Metaspace로 이동시켜 시스템 힙 영역에 저장된다. 덕분에 JVM 힙 영역의 공간이 늘어나고 PermGen Area를 스캔/삭제할 필요가 없어져 GC의 성능이 대폭 향상되었다.
자바 17버전의 zgc 는 GC 작업시 멈추는 시간이 1ms 이하이므로 멈추는걸 못느낀다고 봐도 무방하다. - 장황한 소스 코드 길이
자바는 같은 기능을 하는 코드를 짤 때 다른 언어에 비해 입력해야 할 코드의 양이 많다. 기본적인 구조를 짜기 위해서 필수적으로 작성해야 하는 서식(보일러 플레이트)이랑 코드의 분량이 많다.
그러나 Java는 클래스 지향적이기 때문에 소스코드의 양은 어쩔 수 없는 부분이며, 큰 프로젝트 단위에서 봤을 때, 클래스와 메소드, 변수의 소속이 명확해 파악이 쉽다.
Java
class Main {
public static void main(String args[]) {
System.out.println("Hello World");
}
}
Kotlin
fun main() {
println("Hello World")
}
C
main() {
puts("Hello World");
}
- 마이크로서비스 / 서버리스에 부적합
서버 어플리케이션이 마이크로서비스 / 서버리스로 옮겨가는 추세에서 부각된 문제이다.
마이크로서비스는 대규모 서비스를 소규모의 모듈 단위로 분리하는데, 이 때문에 서비스 별로 인스턴스를 분리해 운용한다. 인스턴스들은 상대적으로 저스펙으로 운영하여야 효율적인데, Java 어플리케이션은 앱 기동을 위해 인스턴스별로 JVM을 필수적으로 설치해야하며 JVM 기동 시 heap 메모리를 충분히 확보해야하므로 다른 언어에 비해 메모리를 상대적으로 더 요구하게 되어 필연적으로 비용 상승의 문제가 발생한다.
서버리스 아키텍처는 상시 가동 상태가 아니라 리퀘스트가 있을 때만 가동이 되는 형태이므로 JVM이 완벽하게 실행된 후 어플리케이션이 동작하는 Java의 경우엔 반응이 느릴 수 밖에 없다. (연산의 부하가 높다면 Java가 더 빠를 수 있음)
참고
'BackEnd > Java' 카테고리의 다른 글
[Java] 배열 (0) | 2022.06.19 |
---|---|
[Java] 조건문과 반복문 (0) | 2022.06.11 |
[Java] 연산자 (0) | 2022.06.06 |
[Java] 변수 (Variable) (0) | 2022.05.29 |
[Java] JVM (0) | 2022.04.30 |