📌 1. Garbage Collection
간단히 설명된 블로그
https://devlog-wjdrbs96.tistory.com/129?category=882228
좀 더 자세히 설명된 블로그
https://mangkyu.tistory.com/118
https://mangkyu.tistory.com/119
동적 할당된 메모리 영역인 Heap에서 더 이상 사용되지 않는 영역을 탐지하여 메모리를 해제하는 기법
Java에서는 Garbage Collector가 필요 없는 객체(Thrash)를 삭제하는 역할을 한다.
🔥GC의 두가지 전제
1. 대부분의 객체는 금방 unreachable(접근 불가능 상태)가 된다.
2. 오래된 객체에서 젊은 객체로의 참조는 아주 적게 존재한다.
이 두가지 전제의 장점을 최대한 살리기 위해 GC는 Old와 Young영역으로 물리적인 공간을 나눈다.
🔥 Young
대부분의 객체가 금방 Unreachable 상태가 되기 때문에, Young 영역에 생겼다가 사라진다. Eden 영역에 생겼다가 사라질 때, Minor GC가 발동한다.
Young은 Eden영역과 2개의 Survivor영역을 갖고 있는데, 최초에 사용되지 않는 객체는 Eden영역에 할당된다. 이후 Eden영역이 꽉 차게 되면 Minor GC가 발동돼서 둘 중 하나의 Survivor 영역으로 이동한다. 다시 하나의 Survivor이 꽉 차게 되면 다른 Survivor로 옮기게 되고, 이 과정을 반복하면서도 살아남은 객체는 Old 영역으로 이동하게 된다.
이 때, 하나의 Survivor영역은 반드시 비어있어야 정상이다.
🔥 Old
객체들이 자꾸 Promotion돼서 Old 영역 메모리가 부족해지면 Major GC가 발동한다. Young 영역은 크기가 작지만, Old영역은 Young 영역보다 크기가 크기 때문에 10배 이상의 시간을 소모한다.
🔥 GC의 공통 동작 방식
1. Stop the world
GC를 실행하는 쓰레드를 제외한 모든 쓰레드를 중지하는 행위
2. Mark and Sweep
사용되는 메모리와 사용되지 않는 메모리를 Mark(식별), 사용되지 않는 메모리를 해제(Sweep)
🔥 GC의 종류
1. Serial GC
CPU 코어가 1개일 때 사용하기 위해 개발. 1개의 쓰레드만 사용한다.
2. Parallel GC
여러개의 쓰레드를 통해 병렬적으로 GC를 수행한다.
그럼에도 불구하고 Stop The world 때문에 앱이 멈추는 것은 피할 수 없었다.
3. CMS ( Concurrent Mark and Sweep )
Parallel GC 처럼 쓰레드를 여러개 사용한다.
다른점은 Mark and Sweep을 Concurrent(동시적)으로 수행한다.
응답이 느려질 순 있지만, 응답이 멈추지는 않는다.
허나 다른 GC보다 메모리와 CPU를 더 많이 필요로 하고, Compact단계를 수행하지 않는다는 단점이 있다. CMS로 GC를 장기적으로 운영하게 되면 조각난 메모리들이 많이 생길 수 있어서, 오히려 Stop the world 시간이 더 길어질 수 있다.
4. G1 ( Garbage First )
기존 GC에서는 Heap 영역을 물리적으로 Young영역과 Old영역 2개로 나누었다.
이와 다르게 G1은 2개로 나누지 않고, Region(지역) 이라는 개념을 도입해서 Heap을 여러 개의 Region으로 나눈다.
각 지역의 역할을 위와 같이 논리적으로 구분한다.
G1의 핵심은 Heap을 여러 개의 동등한 Region으로 나누고, Garbage가 많은 Region에 대해서 우선적으로 GC를 수행한다는 것이다.
📌 2. Vector vs ArrayList
🔥 Vector
Synchronized가 걸려있는 동기적 자료구조. 예전의 자바 클래스가 제공했던 레거시 클래스.
Synchronized가 걸려있으므로 한번의 하나의 쓰레드만 접근할 수 있다.
🔥 ArrayList
Vector와는 다르게 여러 개의 쓰레드가 접근할 수 있는 비동기식 자료구조. java.util 에서 제공하는 자료구조이다.
📌 3. String vs StringBuffer
🔥 String
final이 걸려있어서 불변객체이다. 그래서 문자를 수정하려면 지우고 다시 생성해야 하기 때문에, 여러 번의 수정이 일어날 경우 다른 class를 사용해야 한다.
🔥 StringBuffer & StringBuilder
문자열에서 수정작업이 일어날 경우, 위 클래스들을 사용하면 동일 객체내에서 변경이 가능하므로 String class를 사용하지 말고, 위 클래스를 사용해야 한다.
o 차이점
StringBuffer는 동기화를 지원하기 때문에 Multi-Thread 환경에서 Safe할 수 있다.
StringBuilder는 동기화를 지원하지 않지만, Single-Thread 환경에서는 StringBuffer보다 성능이 뛰어나다.
📌 4. Serialization (직렬화) 란?
자바 시스템 내부에서 사용되는 객체 또는 데이터를 외부에서도 사용할 수 있도록 byte형태로 변환하는 기술
AND
변환된 data를 다시 객체로 변환하는 기술(역직렬화)
메모리적으로 이야기하면, JVM 메모리에 상주하고 있는 객체 데이터를 byte형태로 변환하는 기술
🔥 직렬화는 왜 사용될까?
직렬화의 결과로 CSV, JSON같은 파일이 형성된다. CSV, JSON 등의 파일들은 데이터 교환 시 많이 사용된다.
즉, 자바 직렬화는 자바 시스템간의 데이터 교환을 위해 사용된다.
객체나 data를 직렬화 한다음에, 받는 쪽에서 역직렬화를 하면 데이터 type이 알아서 맞춰지므로 기존 객체처럼 사용할 수 있다.
서블릿 session이나, 캐시등에서 많이 사용된다.
참고 블로그
https://woowabros.github.io/experience/2017/10/17/java-serialize.html
📌 5. Java의 메모리 영역에 대해서 설명해보라
Static , Stack, Heap -> 3가지 영역을 흔히 T자 메모리 영역이라고 한다.
🔥 Static 영역
패키지나, 클래스 정보가 올라간다.
시작될 때 올라가는 것이 아니라, 호출될 때 올라간다.
JVM이 종료될 때까지 유지된다.
🔥 Stack 영역
'{' 여는괄호를 만날 때마다 Stack Frame이 하나씩 생기고, '}' 닫는 괄호를 만날 때마다 Stack Frame이 하나씩 사라진다.
그래서 if, for, while, switch 등등은 모두 Stack Frame이 생기게 된다.
기본형 type 변수값들은 Stack에 저장되고, 참조형 type 변수값들은 참조값만 저장된다.
외부 StackFrame에서 내부로 접근하는 것은 불가능하지만, 내부에서 외부로 접근하는 것은 가능하다.
Thread 역시 Stack에 생성된다. 하나의 쓰레드는 내부적으로 별개의 T자형 메모리 구조를 갖는다.
19번 -> Stack Frame
https://imsfromseoul.tistory.com/144?category=867222
🔥 Heap 영역
생성된 객체들(instance)이 올라간다.
참조 블로그
https://siyoon210.tistory.com/124
📌 6. Overriding vs OverLoading
IN EXTENDS ( 상속에서 )
🔥 OverLoading
두 메서드가 같은 이름을 갖고 있으나, 인자의 수나 자료형이 다른 경우
🔥 OverRiding
상위 타입의 메서드에 대해 하위 타입에서 같은 이름으로 재정의해서 사용하는 것.
자식 객체에서 오버라이딩한 메서드 호출 시 오버라이딩한 메소드인 자식 객체의 메소드가 호출되게 된다.
참조블로그
https://gmlwjd9405.github.io/2018/08/09/java-overloading-vs-overriding.html
📌 7. Abstract vs Interface
인터페이스와 추상클래스 모두 상속받는 클래스가 Abstract Method를 구현하도록 강제하는 공통점을 갖고 있다. 허나 둘은 쓰임새가 다르다.
🔥 Interface
Interface는 명세의 역할을 한다. 즉, 상속받는 클래스들에 대하여 동일한 동작을 강제하기 위해 존재한다. Interface안에는 구체화 된 메소드가 존재하는 것이 불가능하다.
🔥 Abstract
Abstract는 클래스의 확장의 역할을 한다. Abstract안에는 구체화 된 메소드가 존재하는 것이 가능하다.
📌 8. Generic이란?
Generic 이란 클래스에서 사용할 타입을 클래스 외부에서 설정하도록 하는 것.
<> 안에는 참조자료형만 가능하다. (기본자료형은 wrapper클래스를 활용해야 가능하다)
🔥 Generic의 이점
1. data type을 강제해서, 컴파일 단계에서 오류를 발생시킬 수 있다.
📌 9 . Java의 접근 제어자 4가지
1. public
접근 제한이 없다.
2. private
같은 클래스 내에서만 가능
3. default
같은 패키지 내에서만 가능
4. protected
같은 패키지 내에서, 그리고 다른 패키지의 상속된 클래스 내에서 가능
참조블로그
https://88240.tistory.com/448
📌 10. Call by value vs Call by reference
Java는 항상 Call by value다.
https://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value?answertab=votes#tab-top
http://wonwoo.ml/index.php/post/1679
call by reference라면 new 연산자로 새로운 instance값을 할당했을 때 값이 바뀌어야 하지만 그대로임.
그 이유는 d가 가르키는 참조변수의 위치만 이동했기 때문.
위 stackoverflow의 링크에 자세히 설명돼있다.
다른 예로, 만약 Call by reference라면 swap 함수를 발동시켰을 때, a,b의 위치가 변경돼야 하지만 변경되지 않는 것을 볼 수 있다.
그 이유는 swap 함수 parameter a,b에 argument값으로 a의 참조변수 값, b의 참조변수값이 들어갔기 때문.
즉, swap parameter a,b는 새로운 값에 할당이 된 것.
Java 의 경우 항상 call by value 입니다. 자바는 객체를 메서드로 넘길 때 참조하는 지역변수의 실제 주소를 넘기는 것이 아니라 그 지역변수가 가리키고 있는 힙 영역의 객체를 가리키는 새로운 지역변수를 생성하여 그것을 통하여 같은 객체를 가리키도록 하는 방식입니다.
call by value는 메모리의 저장값, call by reference 는 메모리의 주소값을 보내는데 java 의 경우 인자값을 받아서 해당값을 변경하더라도 호출했던 class 내에서의 객체가 변경되지는 않습니다.
출처:
https://jaimemin.tistory.com/1479
🔥 정리
Java는 항상 call by value로 동작한다.
parameter로 값을 넘길 때 주소값을 넘기는게 아니라 새로운 참조변수를 생성해서 그 참조변수가 Heap 영역의 같은 객체를 가르키도록 만든다.
'CS > 기본기 탄탄 🔥시리즈' 카테고리의 다른 글
🔥6 - 데이터 베이스 (1) | 2021.06.08 |
---|---|
🔥5 - 네트워크 (0) | 2021.06.03 |
🔥4 - 운영체제 (0) | 2021.06.02 |
🔥3. Spring (1) (0) | 2021.05.31 |
🔥2. Java(2) (0) | 2021.05.27 |
댓글