JVM은 자바 플랫폼의 초석이다. 하드웨어와 OS 독립성을 보장해주고, 악성 프로그램으로부터 보호하는 기능을 담당하는 기술의 요소이다.
JVM은 추상 컴퓨팅 머신이다. 진짜 컴퓨팅 머신과 같이 명령어 세트가 있고, 런타임에 다양한 메모리 영역을 조작한다.
JVM의 첫번째 프로토타입은 PDA와 유사한 휴대용 장치에서 호스팅하는 소프트웨어의 JVM 명령세트를 에뮬레이트 했다. 현재는 모바일, 데스크탑 및 서버 장치에서 JVM을 에뮬레이트 할 수 있다. JVM 덕분에 자바 프로그램은 특정 구현 기술이나 호스트 하드웨어 또는 호스트 OS에 상관없이, JVM 하고만 상호작용한다. OS의 변경없이 어디서나 실행 가능하다. 다만 JVM은 OS에 종속적이다. -> "write once, run anywhere"
JVM은 프로그래밍 언어에 대해서는 모르고, 특정 바이너리 형식인 클래스 파일만 알고 있다. 클래스 파일에는 JVM 명령어와 기호, 테이블 및 기타 보조 정보가 포함되어 있다.
클래스 파일로 표현할 수 있는 모든 언어는 JVM에서 호스팅 할 수 있다.
출처 : https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-1.html#jvms-1.2
javac [ options ] [ sourcefiles ] [ classes ] [ @argfiles ]
javac
는 자바 언어로 쓰여진 클래스나 인터페이스 정의를 읽는 도구다, 그리고 바이트 코드 클래스 파일로 컴파일 한다. 자바 소스파일 이나 클래스의 주석도 처리할 수 있다.
첫번 째 방법 : 명령줄에 파일 이름 나열
두번 째 방법 : 소스파일이 많으면 파일이름을 공백이나 line breaker로 나눈 뒤에 파일 이름 리스트를 사용하여 javac 명령어를 사용한다.
C:\>dir /B
greetings
C:\>dir greetings /B
Aloha.java
GutenTag.java
Hello.java
Hi.java
C:\>javac greetings\*.java
C:\>dir greetings /B
Aloha.class
Aloha.java
GutenTag.class
GutenTag.java
Hello.class
Hello.java
Hi.class
Hi.java
source파일 이름은 반드시 .java
로 끝나야하고, class file 이름은 반드시 .class
로 끝나야 한다.
InnerClass 정의는 추가적인 classfile을 생성한다. inner랑 outer 이름이 결합하게 된다
MyClass$MyInnerClass.class
반드시 소스파일을 패키지를 반영한 디렉토리로 정렬해야 한다.
java [ options ] <class> [ arguments ... ]
java [ options ] -jar <file.jar> [ arguments ... ]
javaw [ options ] <class> [ arguments ... ]
javaw [ options ] -jar <file.jar> [ arguments ... ]
자바 어플리케이션을 실행하는 명령어이다.
이것은 자바 런타임 환경에서 시작한다. 특정 클래스를 로딩하고 main 메서드를 호출한다.
메서드는 반드시 public 그리고 static으로 선언되어 있어야 한다.
그리고 반드시 어떠한 값도 리턴하면 안된다.
반드시 String array를 파라미터로 받아야 하며, 메서드 시그니처는 public static void main(String[] args)
여야만 한다.
클래스 이름 또는 JAR 파일 이름 뒤에 옵션이 아닌 인수가 main
함수에 전달된다.
javaw
명령은 연결된 콘솔 창이 없다는 java
점을 제외하고 와 동일하다.
javaw
런처는 어떤 이유로 시작이 실패할 경우 오류 정보가 포함된 대화 상자를 표시합니다.
출처 : https://docs.oracle.com/javase/7/docs/technotes/tools/windows/java.html
javap
로소스파일을 .class 파일로 변환할 때, 그 산출물이 JVM이 이해할 수 있는 언어로 만들어지는데, 운영체제에 상관없이 JVM만 있으면 실행이 되도록 하기 위함이다
즉 java 바이트 코드는 바이트 코드로 이루어진 JVM의 명령어 셋이다.
명령어 셋엔 여러종류가 있는데 명령어 셋과 기능에 대해 간략하게 알아보면, 이 정도가 있다.
Load and store (e.g. aload_0
, istore
)
Arithmetic and logic (e.g. ladd
, fcmpl
)
Type conversion (e.g. i2b
, d2i
)
Object creation and manipulation (new
, putfield
)
Operand stack management (e.g. swap
, dup2
)
Control transfer (e.g. ifeq
, goto
)
Method invocation and return (e.g. invokespecial
, areturn
)
출처 : https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html
오라클 JVM을 위한 JIT 컴파일러는 더욱 빠른 실행이 가능하다.
원래는 소스코드를 컴파일하고 바이트코드로 변환하고 자바 인터프리터가 바이트코드를 기계어로 해석하고 실행한다.
JIT 컴파일러는 같은 코드를 매번 해석하지 않고, 쓸만한 코드를 컴파일해두고 사용한다.
한마디로 자주 쓰는 코드를 캐싱, 캐싱된 코드를 가져다 쓰기 때문에 속도를 개선할 수 있는 것
장점은 Java 클래스의 성능을 향상 시키고, 재컴파일을 방지한다는 것, C 컴파일러가 필요 없다는 것, 빈 메서드를 자동으로 제거해준다는 것, 블록 내 하위 표현식을 제거해준다는 것
단점은 초기 구동시에 손해를 본다 (어찌 됐든 첫 컴파일 시 시간과 메모리를 소모하고 저장해두어야 하기 때문) 그리고 런타임에 동적으로 코드를 생성하여 실행한다는 특징 때문에 잠재적으로 보안 문제를 가지고 있다는 것
1) ClassLoader
Java Runtime Eviromental 의 약자
Java 프로그램 실행을 위한 환경을 제공하기 위해 특별히 설계됨
JDK와 같이 플랫폼에 따라 다르고, JVM, JAVA Binary 및 기타 클래스로 구성됨
컴파일러 디버거 등과 같은 개발도구 포함 안됨
프로그램만 실행하기 위해서라면 컴파일 할 필요가 없으므로 JDK가 아닌 JRE만 설치하면 됨
주된 기능은 실행을 위한 환경을 만드는 데 사용됨.
JRE = JVM + 기타 클래스 라이브러리
출처 : https://www.geeksforgeeks.org/difference-between-jdk-and-jre-in-java/