백엔드 개발자로서 다룰 수 있는 언어가 다양하다면 많은 장점이 있을 것이다. 다만 필자는 여러 언어를 얉게 파는 것 보다 주 언어를 더 깊게 파는 것이 더 중요하다고 생각한다.
누구보다 자신있는 주 언어가 생기면 다른 언어를 이해하기도 쉽고 빨리 습득할 수 있다는 것이 필자의 생각이다.
수 많은 개발 언어가 있지만 C, Python, JavaScript 등 과 함께 수년째 주축 개발 언어로써 사용되고 있으며 지속적인 업데이트와 비교적 러닝커브가 낮다는 장점이 있기에 Java를 주 언어로 정했다.
천 가지의 발차기를 한 사람은 무섭지 않다. 다만 한 가지 발차기를 천번 한 사람은 무섭다. -이소룡-
1. 시스템으로부터 메모리 할당 (JVM)
2. Java 컴파일러에 의해 .java -> .class (바이트 코드 변환)
3. 클래스 로더에 의해 클래스 파일들은 JVM에 로드된다.
4. 실행기(Execution Engine)에 의해 클래스 파일을 해석하며 프로그램 실행
지역 변수 : 함수 안에 선언 / 함수가 실행될 때
전역 변수 (필드 변수) : 함수 밖에 선언
1. 클래스 변수 : static 변수
2. 인스턴스 변수 : 객체 변수
변수의 사용처에 따라 적절하게 선언해야 한다.
1. static 변수의 무분별한 사용은 메모리에 악영향을 끼친다.
2. 병렬 프로그래밍에서 잘 못된 변수 사용은 의도치 않은 결과를 발생 시킬 수 있다.
boolean
byte
short
int
long
char
float
double
참조형 데이터의 주소값
String
List
JVM 메모리 영역은 크게 세 영역으로 나눈다.
Java6까지는 new로 선언된 String만 Heap 영역에 저장되었고, literal("")로 선언된 String은 String Constant Pool (Permanent)에 저장되었었다.
하지만 Java7 부터 Perm 영역이 사라지고 Constant Pool의 저장 영역이 Heap으로 옮겨졌다.
기존의 Permanent 영역은 Metaspace라는 영역이 대체하였고, Perm에 있던 Constant Pool 영역은 Heap으로 옮겨지면서 이제 literal로 선언된 String도 GC 대상이 되었다.
GC란? Java에서 메모리 누수를 방지하기 위해 사용하는 방법으로 JVM의 힙 영역에 존재하는 오브젝트들 중에서 더이상 사용되지 않는 오브젝트들을 지우고 해당 오브젝트에 할당되었던 메모리를 반환 받는 작업을 일컫는다.
Old Generation 영역이 가득차게 되면 Major GC가 발생한다.
아래 예제 코드를 통해 메모리 할당 과정을 살펴보고 어떻게 GC의 대상이 되는지 확인해보자.
public class Main {
public static void main(String[] args) {
String url = "https://"; // 지역 변수, 참조형 데이터
url += "skysoo1111.github.io";
System.out.println(url);
}
}
String은 참조형 변수이기 때문에 힙 영역에 할당되고, 그 주소값은 스택 영역에 할당된다.
String url = "https://";
url 변수에 String 값을 더하면서 값이 변동되는데, 이때 기존에 할당된 값을 변경하는 것이 아니라 힙 영역에 새롭게 값이 할당된다.
url += "skysoo1111.github.io";
그로 인해 자연스레 기존에 힙 영역에 할당되었던 값은 더이상 참조하지 않는 값이 되면서 Unreachable 객체 (GC 대상)가 된다.
이렇게 Unreachable 객체는 Minor GC 과정에서 삭제되고, 살아남은 Reachable 객체들은 Suvivor0 -> Suvivor1 -> Old 순으로 영역을 이동하고 이동하는 객체들의 Age는 증가한다.