3 분 소요


Thread Local

Spring MVC는 멀티 스레드 기반으로 동작하는 웹 프레임워크다.
매번 요청이 올 때마다 스레드를 만들어서 실행하면 비용이 커지므로, 스레드 풀을 사용한다.
ThreadLocal은 각 스레드에 할당되는 저장 공간인데, 스프링과 같은 멀티 스레드 프로그래밍 환경에서는 스레드가 재사용되기 때문에, ThreadLocal에 값을 저장하고 해제하지 않으면 문제가 발생한다.
대표적으로 Spring Security에서 사용되는 SecurityContextHolder는 ThreadLocal을 사용한다.


CDN

CDN(Content Delivery Network)은 물리적으로 떨어져 있는 사용자에게 컨텐츠를 더 빠르게 제공하기 위해 고안된 기술이다.
만약 우리나라 사람이 미국에 있는 서버로부터 이미지나 파일 등을 다운받으려고 하면 시간이 오래 걸리는데, 느린 응답속도와 다운로드 시간을 극복하기 위해 서버를 분산시켜 캐싱해두고, 빠르게 다운받을 수 있게 한다.

CDN은 콘텐츠에 대한 요청이 발생하면 사용자와 가장 가까운 위치에 존재하는 서버로 매핑시켜, 요청된 파일의 캐싱된 버전(사전에 저장된)으로 요청을 처리한다.
서버가 파일을 찾는 데 실패할 경우 CDN 플랫폼의 다른 서버에서 콘텐츠를 찾은 다음 유저에게 응답을 전송한다.


JVM 메모리 영역

  • Method : 클래스가 로딩될 때 생성되며, 클래스, 메소드 정보, static 변수가 저장된다.
  • Heap : 런타임 시 할당되며 주로 객체가 저장된다.(new 키워드)
    • GC를 통해 메모리가 정리된다.
  • Stack : 컴파일 시 할당되며, 지역 변수 등 임시 값이 생성되는 영역
    • 메소드를 호출할 때 개별적으로 생성되며 종료시 해제
  • PC Register : 스레드가 생성될 때 마다 생성되며, 현재 스레드가 실행되는 부분의 주소와 명령을 저장한다.
  • Native : 자바 외의 언어로 작성된 코드를 위한 영역.


추상 클래스와 인터페이스

  • 추상 클래스는 클래스 내 추상 메소드가 하나 이상 포함되거나 abstract로 정의된 경우를 말한다.
  • 인터페이스는 모든 메소드가 추상 메소드로만 이루어져 있는 것을 말한다.

공통점

  • new 연산자로 인스턴스 생성 불가능
  • 사용하기 위해서는 하위 클래스에서 확장/구현해야 한다.

차이점

  • 인터페이스는 그 인터페이스를 구현하는 모든 클래스에 대해 특정한 메소드가 반드시 존재하도록 강제한다.
  • 추상 클래스는 상속받는 클래스들의 공통적인 로직을 추상화 시키고, 기능 확장을 위해 사용한다.
  • 추상 클래스는 다중 상속이 불가능하지만, 인터페이스는 다중 상속이 가능하다.

Java 버전이 올라갈수록 Interface가 abstract의 기능을 흡수하고 있다.
Java8부터는 interface에서 default method 사용이 가능해졌다.
Java9부터는 interface에서 private method 사용이 가능해졌다.


제네릭

클래스 내부에서 사용할 데이터 타입을 외부에서 지정하는 기법.

  • 제네릭으로 선언한 클래스는 내가 원하는 타입으로 만들어서 사용이 가능.
  • <>안에는 참조 자료형(Class, Interface, Array)만 가능
  • 기본 자료형을 사용하기 위해선 Wrapper 클래스를 활용

사용 이유

타입이 안전하다는 장점과 코드의 중복을 제거하는 편의성.


직렬화(Serialization)

자바 시스템 내부에서 사용되는 객체, 데이터를 외부 자바 시스템에서도 사용할 수 있도록 byte 형태로 데이터를 변환하는 기술.

각 OS마다 다른 가상 메모리 주소 공간을 갖기 때문에, Reference Type의 데이터들은 인스턴스를 전달할 수 없다.
이런 문제를 해결하기 위해 주소값이 아닌 byte 형태로 직렬화된 객체 데이터를 전달해야 한다.

따라서, 전송 및 저장이 가능한 데이터로 만들어주는 것이 직렬화이다.


클래스와 구조체의 차이

구조체는 하나의 구조로 묶일 수 있는 변수들의 집합.
클래스는 변수뿐만 아니라, 메소드도 포함 가능.


메모리 할당 알고리즘

  • First Fit : 메모리의 처음부터 검사해서 크기가 충분한 첫 번째 메모리에 할당
  • Next Fit : 마지막으로 참조한 메모리 공간에서부터 탐색을 시작해 공간을 찾음
  • Best Fit : 모든 메모리 공간을 검사해서 내부 단편화를 최소화하는 공간에 할당

단편화

  • 외부 단편화 : 작업보다 많은 공간이 있더라도, 작업을 받아들일 수 없는 경우
    • 메모리 배치에 따라 발생하는 문제
  • 내부 단편화 : 작업에 필요한 공간보다 많은 공간을 할당 받음으로써 발생하는 내부의 사용 불가능한 공간


메모리 단편화 해결 방법

페이징

프로세스의 주소 공간을 고정된 사이즈의 페이지 단위로 나누어, 물리적 메모리에 불연속적으로 할당하는 방식

  • 메모리는 Frame, 프로세스는 Page라는 고정 크기로 분할
    • Frame Size == Page Size
  • Page와 Frame을 대응시키는 page mapping 과정이 필요하여 paging table을 생성해야 한다.
  • 연속적이지 않은 공간도 활용할 수 있기 때문에, 외부 단편화 문제 해결

문제점

프로세스의 크기가 Page 크기의 배수가 아닐 경우 마지막 Page에 내부 단편화가 발생한다.

  • 페이지의 크기가 증가하면 내부 단편화가 커진다.
  • 페이지 단위를 작게 하면 내부 단편화 문제도 해결할 수 있지만, Page Mapping 과정이 많아지므로 효율이 떨어진다.

세그멘테이션

프로세스를 서로 크기가 다른 논리적 블록 단위인 Segment로 분할하여 메모리에 할당하는 방식

  • 각 Segment는 연속적인 공간에 저장
  • Segment들이 크기가 서로 다르기 때문에, 프로세스가 메모리에 적재될 때, 빈 공간을 찾아 할당하는 기법.
  • 페이징과 마찬가지로 mapping을 위한 Segment Table이 필요하다.

문제점

프로세스가 필요한 메모리 공간만큼 메모리를 할당해주기 때문에 내부 단편화 문제는 발생하지 않지만, 중간에 메모리를 해제하면 생기는 외부 단편화 문제가 발생.


가상 메모리

메모리에 로드되어 실행중인 프로세스가 메모리가 아닌 가상의 공간을 참조해, 마치 큰 물리 메모리를 갖는 것 처럼 사용할 수 있게 해주는 기법.

실제 메모리 안에서 공간이 부족하면 현재 사용하고 있지 않은 데이터를 빼서, 가상 메모리에 저장해두고, 실제 메모리에선 처리만 하게 하는 것이 가상 메모리의 역할.


fork, vfork

  • fork() : 부모 프로세스의 메모리를 복사해서 사용
  • vfork() : 부모 프로세스와의 메모리를 공유
    • fork()보다 생성 속도가 빠르다.
    • 자원을 공유하기 때문에 자원에 대한 race condition이 발생하지 않도록 하기 위해 부모 프로세스는 자식 프로세스가 exit 하거나 execute가 호출되기 전까지 block

race condition
두 개 이상의 프로세스가 공통 자원을 병행적으로 읽거나 쓸 때, 공용 데이터가 접근 순서에 따라 실행 결과가 달라지는 상황.

댓글남기기