Java는 Sun Microsystems의 James Gosling과 Green 프로젝트 연구팀이 만들어 1995년 발표했다.
당시 가전제품이 다양한 하드웨어 및 소프트웨어 환경에서 운영되고 있었기 때문에, 특정 하드웨어에 종속되지 않는 소프트웨어 플랫폼이 필요했다. Green 프로젝트의 목표는 모든 가전제품에서 동작할 수 있는 플랫폼 독립적인 프로그래밍 언어와 런타임 환경을 개발하고 통신 기능을 내장하는 것이었다.
James Gosling은 초기에 C++로 운영체제를 만들려고 시도했지만 C++의 복잡성으로 실패하고, C++의 문제점(플랫폼 종속성, 메모리 관리, 복잡성)을 해결한 프로젝트를 위한 언어 Oak를 만들었다.
Java라고 불리기 이전엔 James Gosling의 사무실 밖에 있던 오크 나무에서 따온 ‘Oak’로 불렸다. 하지만 ‘Oak’는 이미 Oak Technology의 상표로 등록되어 있어 이름을 변경해야 했는데, 인도네시아의 커피 재배지 자바 섬에서 따와 ‘Java’라는 이름이 붙게 되었다.
Mount Merapi, Central Java, Indonesia / https://www.triptipedia.com/tip/Wvj2HwL/get-to-know-more-about-the-island-of-java
1993년 그래픽 기반 World Wide Web이 발표되고, 1994년 당시 웹 브라우저의 표준이 되었던 Netscape Navigator가 발표되는 등 Java가 탄생한 시기(1995년)는 웹 기술이 급속도로 성장하고 있던 시기였다.
플랫폼 독립적인 Java의 특징은 웹 기반 응용 프로그램에 적합했고, Sun은 “Write Once, Run EveryWhere” 라는 슬로건으로 Java를 홍보했다.
이후 Java는 초기 설계 목표를 넘어 오늘날 널리 사용되는 범용 프로그래밍 언어로 발전했다.
James Gosling이 왜 자바를 만들었는지, 어떤 생각을 하며 만들었는지 알 수 있는 인터뷰 영상이 하나 있다.
https://youtu.be/RrMptmNYkSw?si=oo5KeXzqwS-Z9wFj
Java는 다음과 같은 목표로 설계되었다.
Java 언어 설계 목적 5가지
https://www.oracle.com/java/technologies/introduction-to-java.html
JIT(just-in-time): 런타임에 코드를 컴파일 하는 기술로, 인터프리터 언어에서 실행 시간 최적화를 위해 주로 사용한다.

C언어는 소스코드가 컴파일되어 기계어로 변환되면 바로 실행된다.
하지만 자바 컴파일러는 바로 기계어로 변환하지 않고, 플랫폼에 중립적인 바이트 코드(byte code)를 생성한다. 이후, 바이트 코드는 JVM에 의해 해석되어 실행된다.
Compile Time
javac Mycode.java 를 입력하면 Java 컴파일러가 syntax error, compile time error를 확인한 후 java code를 플랫폼 중립적인 bytecode로 변환한다. bytecode는 JVM을 통해서만 실행시킬 수 있다.Run Time
JIT는 어떤 원리로 애플리케이션을 더 빠르게 만들까?
먼저, JIT 컴파일러 없이 인터프리터로만 동작하는 경우를 생각해보자.

인터프리터는 bytecode 명령어와 해당 플랫폼의 기계어 명령어 간의 매핑 정보를 사용해 bytecode를 한 줄씩 기계어로 변환한다.
인터프리터만 사용하면 컴파일 시간이 소모되지 않아 애플리케이션을 로드하고 시작하는 시간은 빠르다.
하지만, 동일한 코드가 반복될 때마다 매번 기계어로 변환하기 때문에 비효율적이고 런타임 성능이 떨어진다. (No optimization)
여러 번 실행된 코드는 앞으로도 많이 실행될 것이니까 반복되는 코드를 캐싱하면 성능을 개선할 수 있지 않을까?
이를 위해, JVM은 코드 스니펫이 실제로 몇 번 실행되었는지 performance counter를 유지한다.
코드가 반복적으로 실행되어 특정 counter값에 도달할 경우, 컴파일후 컴파일된 복사본을 JVM의 code cache에 저장하고 기본적인 최적화를 수행한다.
메서드 인라이닝, 빠른 메서드 호출, 간단한 루프 최적화, 널체크 제거, 강제 명령어 재배치, 간단한 상수 전파, 스택 프레임 최적화 등
이 작업을 하는 JIT 컴파일러가 c1 compiler다.
c1 컴파일러는 낮은 수준의 최적화를 하고, 코드 캐시에 저장한다.
performance counters - Interpreter가 코드를 변환하면서 어떤 코드가 몇 번 실행되는지 기억한다.
컴파일하고 컴파일된 복사본을 저장해 optimize하는것이 낫다
240MB(java8)의 code cache에 저장함.
-XX:InitialCodeCacheSize= : 시작 시 코드 캐시 사이즈
-XX:ReservedCodeCasheSize= : 코드캐시 사이즈 최대치
-XX:CodeCacheExpansionSize= : 코드 캐시 사이즈가 늘어나는 단위 설정