JVM은 시스템으로부터 프로그램을 수행하는데 필요한 메모리를 할당받고, 이를 여러 영역으로 나누어 관리한다. 메서드 영역 클래스파일(.class)을 읽고 분석하여 클래스의 정보와 클래스 변수를 메서드 영역에 저장한다. 호출 스택(Call Stack) 메서드가 호출되면 메서드를 위한 메모리가 할당되며, 메서드가 작업을 수행하는 동안 지역변수들과 연산의 중간결과 등이 저장된다. 메서드가 작업을 마치면 할당되었던 메모리 공간은 반환되어 비워진다. 호출 스택의 특징 메서드가 호출되면 수해엥 필요한 메모리를 스택에 할당받는다. 메서드가 수행을 마치면 사용했던 메모리를 반환하고 스택에서 제거된다. 호출스택의 제일 위에 있는 메서드가 현재 실행 중인 메서드이다. 아래에 있는 메서드가 바로 위의 메서드를 호출한 메서드..
객체지향언어 객체지향이론의 기본 개념 실제 세계는 사물(객체)로 이루어져 있으며, 발생하는 모든 사건들은 사물 간의 상호작용이다. 실제 사물의 속성과 기능을 분석한 다음, 데이터(변수)와 함수로 정의함으로써 실제 세계를 컴퓨터 속으로 옮기는 것이다. 객체지향 언어의 특징 코드의 재사용성이 높다. 코드의 관리가 용이하다. 신뢰성이 높은 프로그래밍을 가능하게 한다. 클래스와 객체 클래스 객체를 정의해 놓은 것 객체의 설계도 혹은 틀 객체 실제로 존재하는 것 유형 뿐만 아니라 무형적인 것도 해당되기 때문에 사물은 물론 개념이나 논리 등도 객체에 해당된다. 클래스 객체 제품 설계도 제품 TV 설계도 TV 붕어빵 기계 붕어빵 클래스는 객체를 만들기 위해 사용한다. 객체와 인스턴스 클래스로부터 객체를 만드는 과정을..
volatile volatile을 통해 캐시와 메모리 간의 불일치를 해소할 수 있다. 성능 향상을 위해 변수의 값을 core의 cache에 저장해 놓고 작업을 하게 된다. 멀티 코어 프로세서에서는 위처럼 코어마다 별도의 캐시를 가지고 있다. 코어는 메모리에서 읽어온 값을 캐시에 저장하고 캐시에서 값을 읽어서 작업을 한다. 같은 값을 읽어올 때는 먼저 캐시에 있는지 확인하고 없을 때만 메모리에서 읽어온다. 따라서 도중에 메모리에 저장된 변수의 값이 변경되었는데도 캐시에 저장된 값이 갱신되지 않아서 메모리에 저장된 값과 캐시에 저장된 값이 다른 경우가 발생한다. 변수에 앞에 volatile을 붙이면 코어가 변수의 값을 일거올 때 캐시가 아니라 메모리에서 읽어오기 때문에 캐시와 메모리 간의 값의 불일치가 해소..
synchronized 블록 외에도 동기화할 수 있는 방법이 있다. java.util.concurrent.locks 패키지가 제공하는 lock 클래스들을 이용하는 방법이다. ReentrantLock재진입이 가능한 lock, 가장 일반적은 배타 lock ReentrantReadWriteLock읽기에는 공유적이고, 쓰기에는 배타적인 lock StampedLockReentrantReadWriteLock에 낙관적인 lock의 기능을 추가 ReentrantLock은 wait(), notify()처럼 특정 조건에서 lock을 풀고 나중에 다시 lock을 얻고 임계영역으로 들어와서 이후의 작업을 수행한다. 앞서 다뤘던 lock과 일치한다. ReentrantReadWriteLock은 읽기 lock이 걸려있으면 다른 스..
동기화의 효율을 높이기 위해 wait(), notify()를 사용한다. 만일 계좌에 출금할 돈이 부족해서 한 스레드가 락을 보유한 채로 돈이 입금될 때까지 계속 기다린다면 다른 스레드들은 모두 해당 객체의 락이 풀리는 것을 기다리느라 다른 작업들도 원활히 진행되지 않는다. 이 경우 wait()과 notify()를 사용하여 효율을 높일 수 있다. Object 클래스에 정의되어 있으며, 동기화 블록 내에서만 사용할 수 있다. wait() : 객체의 lock을 풀고 스레드를 해당 객체의 waiting pool에 넣는다. notify() : waiting pool에서 대기 중인 스레드 중의 하나를 깨운다. notifyAll() : waiting pool에서 대기 중인 모든 스레드를 깨운다. class Accou..
멀티 스레드 프로세스에서는 다른 스레드의 작업에 영향을 미칠 수 있다. 진행 중인 작업이 다른 스레드에게 간섭받지 않게 하려면 동기화가 필요 스레드의 동기화 한 스레드가 진행 중인 작업을 다른 스레드가 간섭하지 못하게 막는 것 동기화하려면 간섭받지 않아야 하는 문장들을 '임계 영역'으로 설정 임계영역은 락(lock)을 얻은 단 하나의 스레드만 출입가능(객체 1개에 락 1개) synchronized를 이용한 동기화 synchronized로 임계영역(lock이 걸리는 영역)을 설정하는 방법 2가지 1. 메서드 전체를 임계 영역으로 지정 public synchronized void calcSum() { //... } 2. 특정한 영역을 임계 영역으로 지정 synchronized(객체의 참조변수) { // 참조..