마지막 업데이트 : 2015. 08. 28
추가할 내용
자바 도서 3권 dyd, Effective Java, 여러 Article, Java 7-8 업데이트 내용, Oracle Coding Convention, Oracle Document
객체지향 언어로서 코드의 화려함보다는 소프트웨어의 구조를 중요시한다
자바 컴파일러에 의해서 생성되는 코드를 가리켜 “자바 바이트코드”라 하는데, 이는 자바 컴파일러에 의해서 생성되는 코드의 명령어 크기가 1바이트이기 때문에 붙여진 이름이다
대부분의 소프트웨어는 속도보다 안전성이 우선시된다 물론 속도는 중요하다. 하지만 여기서 말하는 속도는 소프트웨어의 개발 속도이다 개발 중인 소프트웨어의 90% 이상은 인터넷, 네트워크 기반 소프트웨어이다 인터넷, 네트워크상에서는 소프트웨어의 속도보다 데이터의 전송속도가 더 중요하다 속도가 문제가 되면 대부분의 개발자들은 데이터베이스를 먼저 의심한다. 그리고 그곳에서 대부분 문제를 발견하고 해결한다
단순히 메모리 공간만 가지고 보면 적은 메모리를 사용하는 변수를 Short와 같은 자료형을 사용하는 게 좋을 것 같지만 중요한 사실은 정수 연산의 관점에서는 다르다는 것이다.
일반적으로 우리가 사용하는 CPU는 int형 정수 연산을 가장 고속으로 처리하게끔 설계되어 있다
따라서 자바는 정수형 연산을 진행할 때(덧셈이건 뺄셈이건), 모든 피연산자를 int형으로 변환하는 과정을 거친다. 때문에 정수형 연산을 위해서 short 자료형보다는 int형의 실행 속도가 더 빠르다
단, long형에서의 int형으로의 변환은 일어나지 않는다
4바이트로 표현되는 float는 6자리의 정밀도 (소수점 이하 6자리 정밀도)를 가지고
double은 15자리의 정밀도(소수점 이하 15자리의 정밀도)를 갖기 때문에,
표현하고자 하는 값에서 요구하는 정밀도를 기준으로 자료형을 선택하게 된다
소수점 이하 15자리까지 오차가 발생하지 않는다고 해도, 그 이하부터는 오차가 발생하기 때문에,
오차가 존재하는 double형 변수 둘 이상을 더하다 보면, 소수점 이하 15자리가 아니라,
소수점 이하 셋째 자리에서도 오차가 발생할 수 있다.
따라서 실수의 계산은 기본적으로 오차가 존재한다고 인식해야 한다
하드웨어가 숫자밖에 인식을 못하니 문자를 숫자로 표현하는 수밖에 없다.
그래서 문자를 숫자로 표현하기 위한 몇몇 표준이 프로그래밍 언어에 상관없이 만들어졌는데,
자바는 이 중에서 유니코드(unicode)라는 표준을 근거로 문자를 표현하고 있다.
유니코드는 문자 하나를 2바이트로 표현하는 문자 체계이다.
2바이트로 표현할 수 있는 데이터의 수는 2의 16승 개이므로
총 6만 개 이상의 문자 표현이 가능하다는 계산이 나온다.
따라서 유니코드는 세계의 모든 언어를 표현할 수 있는 문자 체계이다.
문자는 작은따옴표로 표현이 된다
char형 변수는 문자의 저장을 위해 사용된다.
char형 변수에 실제 저장되는 것은 저장되는 문자의 유니코드 상수 값이다
int num = 1+5
여기서 1+5는 변수의 상대적 개념인 상수(=리터럴)라 부른다.
상수라 부르는 이유는 값이 변경될 수 없기 때문이다
하지만 상수도 메모리 공간에 저장이 된다.
CPU를 통해서 연산이 이루어지기 때문이다.
해당 연산의 상수들은 기본자료형으로 표현 및 저장된다
모든 정수형 상수는 int형으로
모든 실수형 상수는 double형으로
그래서 long으로 선언된 자료형에 저장하려고 해도 접미사를 붙여야 하는 것이다
그래서 float로 선언된 자료형에 저장하려고 해도 접미사를 붙여야 하는 것이다
: 자바 컴파일러는 상황에서 값의 크기를 기준으로 판단하지 않고, 값의 표현에 사용되는 바이트 크기를 기준으로 판단을 한다.
프로그래머가 별도의 형 변환 명령을 내리지 않아도 형 변환이 발생하는 대표적인 사례
double num1 = 20; //int형 정수 20이 double형 실수 20.0으로 자동 형 변환되어 변수에 저장된다.
하지만 다음의 경우에는 자동으로 형 변환이 발생하지 않는다
int num2 = 20.5; // 컴파일 에러
이처럼 자바에서는 데이터의 손실이 발생하지 않거나, 발생하더라도 그 손실이 제한적인 경우에만 자동 형 변환을 허용한다. 다음은 자바에서 정의하고 있는 자동 형 변환 규칙이다
byte -> short(or char) -> int -> long -> float ->double
가장 빠르게 연산을 진행하기 위한 계산방식
(A) && (B) // A가 false이면 B는 확인하지 않는다
(A) || (B) // A가 true이면 B는 확인하지 않는다
| //비트단위로 OR 연산을 한다*
^ //비트단위로 XOR 연산을 한다 (서로 다르면 1, 같으면 0)
~ //모든 비트를 반전시켜서 얻은 결과를 반환
<< //비트 열을 왼쪽으로 이동(2의 배수의 곱)
(ex 2 <<1 = 4, 2 << 2 = 8, 2 << 3 = 16) : 이동에 따른 빈 공간은 0으로 채운다
>> //비트 열을 오른쪽으로 이동(2의 배수의 나눗셈)
(ex 8 >> 1 = 4, 8 >> 2 = 2) : 이동에 따른 빈 공간은 음수의 경우 1, 양수의 경우 0으로 채운다
>>> //피연산자의 비트 열을 오른쪽으로 이동
기본적으로 Camel Convention
상수는 대문자, 두 단어 이상의 합성어는 _를 포함
패스는 경로의 의미를 지닌다. 클래스 패스는 “클래스의 경로(클래스가 존재하는 경로)”를 뜻한다.
자바 가상 머신은 프로그램의 실행 과정에서 실행에 필요한 클래스를 찾을 때, 바로 이 클래스 패스를 기준으로 찾게 된다
여러 팀 간의 같은 Naming으로 인한 충돌을 방지하기 위해 소스파일들의 경계에 의미를 부여.
패키 지간의 의존관계를 확인하기 위해 (접근제어를 분리하기 위해)
final
- 변경할 수 없음을 의미 클래스,
- 내부 클래스, 메소드, 변수에 선언 가능
- 클래스에 선언하면 다른 클래스가 이 클래스를 상속할 수 없음
- 메소드에 선언하면 다른 클래스에서 이 메소드를 오버 라이딩할 수 없음
- 변수에 선언하면 일단 값이 할당된 이후에는 더 이상 값을 변경할 수 없음
abstract
- 메소드 몸체를 가질 수 없음
- 메소드의 몸체를 하위 클래스에서 정의하게 하고 싶을 때 사용하는 제한자
- abstract가 선언된 메소드를 추상 메소드라고 한다
- 추상 메소드를 포함한 클래스는 반드시 abstract로 선언해야 하며 이를 추상 클래스라 한다
- 추상 클래스를 사용하기 위해서는 상속해서 미구현 메소드를 구현해야 한다
static
- 메소드나 변수를 메모리에 로딩해서 다른 클래스가 이 클래스의 인스턴스를 생성하지 않고도 사용할 수 있게 해준다
- 내부 클래스, 메소드, 변수에 선언 가능
- 인스턴스 또는 클래스명으로 접근 가능
native
- 다른 언어로 작성된 메소드를 자바에서 사용하기 위해 선언하는 제한자
- 메소드에만 선언 가능
- 메소드 몸체를 가질 수 없다
synchronized
- 하나 이상의 스레드가 코드의 특정 블록을 동시에 접근하는 것을 제어하기 위해 사용
- 메소드와 블록에 선언 가능
transient
- JPA는 @Transient와 다름을 유의, 이것은 자바의 예약 업으로 transient int age와 같이 사용한다
- 직렬화 객체 데이터 중 일부의 데이터를 여러 가지 이유로 전송하고 싶지 않을 경우, 이러한 변수는 직렬화에서 제외해야 되며, 이를 위해서 변수에 transient를 선언한다
volatile
- 참고 1 (http://thswave.github.io/java/2015/03/08/java-volatile.html )
- 참고 2 (http://kwanseob.blogspot.kr/2012/08/java-volatile.html)
- 최적화(reordering) 방지 및 멀티스레드 환경에서 데이터 캐시가 일어나지 않도록 한다 (항상 메인 메모리에서 읽도록, 최신의 값을 가져오도록 한다)
- 보통 공유되는 static 데이터에 적합
public
default
- 접근제어자를 선언하지 않는다.
- 동일한 패키지 내에서만 접근이 가능하다
static
- 메소드나 변수를 메모리에 로딩해서 다른 클래스가 이 클래스의 인스턴스를 생성하지 않고도 사용할 수 있게 해준다
- 내부 클래스에서 사용 가능
final
- 다른 클래스에서 이 클래스를 상속받을 수 없음
abstract
- 하위 클래스에서 abstract method를 구현하게끔 강제
간단한 테스트
- public class A 에 public 생성자 : 다른 패키지에서 import 가능, 접근 가능
- class A 에 public 생성자 : 다른 패키지에서 import 불가
- public class A 에 default 생성자 : 다른 패키지에서 import 가능, 접근 불가
방법 1.
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String str = br.readLine();int num = Integer.parseInt(str);
방법 2.
Scanner sc = new Scanner(System.in)
int num = sc.nextInt(); //nextLine() -> String 반환
is a (상속)
has a (복합 관계)
데이터를 파일에 쓰거나, 네트워크를 타고 다른 곳에 전송할 때는 데이터를 바이트 단위로 분해하여 순차적으로 보내야 한다. 이것을 직렬화(Serialization)라고 한다.
기본 자료형은 정해진 바이트의 변수이기 대문에 바이트 단위로 분해하여 전송한 후 다시 조립하는데 문제가 없다. 하지만 객체의 크기는 가변적이며, 객체를 구성하는 자료형들의 종류와 수에 따라 객체의 크기는 다양하게 바뀔 수 있다. 이런 객체를 직렬화 하기 위해서 Serializable 인터페이스를 구현하게 된다
직렬 화가 가능한 객체의 조건 기본형 타입 Serializable 인터페이스를 구현한 객체 여야 한다. 해당 객체의 멤버들 중에 Serializable 인터페이스가 구현되지 않은 게 존재하면 안 된다 transient가 사용된 멤버는 전송되지 않는다 객체 직렬화는 객체에 implements Serializable만 선언해 주면 된다
메소드 (method area)
메소드의 바이트코드 -> 프로그램의 흐름을 구성하는 바이트 코드,
사실상 컴파일된 바이트코드의 대부분이기 때문에, 전체 바이트코드가 올라간다고 봐도 무리가 없다,
당연히 static 메소드, static 변수도 포함된다
스택 (stack area)
지역변수, 매개변수
힙 (heap area)
인스턴스 등
finalize
인스턴스가 소멸되기 직전에 자바 가상 머신에 의해서 자동으로 호출되는 메소드, 그러나 호출 보장이 안된다 (gc타이밍은 예측불가. gc가 동작해도 인스턴스의 완전한 소멸은 유보될 수 있기 때문에, 그래서 공식처럼 System.gc(); System.runFinalization()을 쓴다는데 이런 짓 하지 마라)
equals
동일성, 동등성 ( == 로 비교하는 건 무조건 동등성, equals는 기본적으로 동등성 비교인데 오버라이드 해서 동일성 비교하도록 한다)
clone
- shallow copy : reference를 복사 -> Clonable Interface 참조
- deep copy : 새로운 reference를 생성해서 참조한다 -> Clonable Interface 참조, clone 메서드를 오버 라이딩해서 직접 구현
기본 자료형 데이터를 인스턴스화 시키는 작업을 가리켜 Boxing이라고 한다 (오토 박싱, 오토 언박싱)
사실상 컴퓨터에게 난수를 생성하도록 요구하는 것은 사실상 불가능에 가깝다.
그래서 컴퓨터가 생성하는 난수를 가리켜 “Pseudo-random number”라 하는데, 이는 “가짜 난수”라는 뜻이다. 때문에 우리는 보다 정확한 랜덤 값을 얻기 위해 Seed값을 설정한다. Seed값이 같으면 동일한 결과와 순서로 출력한다. 일반적으로 System.currentTimeMille()같이 unixtime 값을 seed로 많이 사용한다. (default도 이렇게 돼있음)
제네릭은 “일반화”한다는 뜻을 담고 있다. 그리고 그 일반화의 대상은 자료형이다
Object를 써도 되잖아?
- 컴파일 과정에서 발견되는 오류를 검출할 수 있다
- 자료형에 대한 안전성이 보장된다
- 상황에 따라서 둘 이상의 클래스를 정의할 수 있다
정의 방법
- 클래스에 대한 제네릭 정의
class <T>
- 메서드에 대한 정의 방법
public <T> void test(T t)
public <T, Y> void test(T t, Y y)
- 제네릭 매개변수에 대한 제한조건
<T extends (Interface or Upperclass)>
- 제네릭 변수의 와일드카드 선언
와일드카드란 이름 또는 문자열에 제한을 가하지 않음을 명시하는 용도로 사용되는 특별한 기호
파일의 이름을 명시하는데 *가 와일드카드로 사용되었다.
이렇듯 자바는 클래스의 이름을 명시하는 데 있어서 와일드카드로 사용되는 기호?를 정의하고 있다.
- 그리고 이를 기반으로 다음과 같이 변수 또는 매개변수가 선언될 수 있도록 하고 있다
FroutBox <? extends Fruit> box1 = new FruitBox <Fruit>();
이것은 매개변수에 제네릭 객체를 선언함에 있어 유용하다.
특징
- 컬렉션 프레임워크의 인터페이스 구조 Collection <E> : iterable 인터페이스를 상속한다.
- 순회할 수 있도록 iterator 메소드가 정의되어 있다
iterator
컬렉션 클래스의 종류에 상관없이 동일한 형태의 데이터 참조 방식을 유지한다
오름차순을 보장
종류
Set <E>
List <E>
Queue <E>
Map <K, V>
List
동일한 인스턴스의 중복 저장을 허용한다.
인스턴스의 저장 순서가 유지된다
ArrayList (배열과 비슷, 하지만 자동 용량 증가 등의 편의성)
저장소의 용량을 늘리는 과정에서 많은 시간이 소요된다 (선형 자료구조)
데이터의 삭제에 필요한 연산과정이 매우 길다 (뒤에 저장된 데이터들을 한 칸씩 앞으로 이동)
데이터의 참조가 용이해서 빠른 참조가 가능하다
LinkedList (비선형 자료구조)
저장소의 용량을 늘리는 과정이 간단하다
데이터의 삭제가 매우 간단하다
데이터의 참조가 다소 불편하다
Set <E>
수학에서 말하는 “집합”의 특성을 가진다
List <E>를 구현하는 클래스들과 달리 Set <E>를 구현하는 클래스들은 데이터의 저장 순서를 유지하지 않는다. List <E>를 구현하는 클래스들과 달리 Set <E>를 구현하는 클래스들은 데이터의 중복 저장을 허용하지 않는다
HashSet <E>
객체를 담을 때에는 동등 비교를 equals 메소드의 호출 결과와 hashCode 메소드의 호출 결과를 가지고 한다
매우 빠른 검색 속도 -> 매우 빠른 저장 속도
TreeSet <E>
트리 자료구조를 기반으로 구현되어 있는데, “트리”는 데이터를 정렬된 상태로 저장하는 자료구조이다.
따라서 이를 기반으로 구현된 TreeSet <E> 클래스 역시 데이터를 정렬된 상태로 유지한다
객체의 경우, Comparable을 구현해야지 자료구조를 이용할 수 있다
Map <K, V>
HashMap <K, V>
Hash 알고리즘 사용, 매우 빠른 검색 속도
value에 상관없이 중복된 Key의 저장은 불가능하다
value는 같더라도 key가 다르면 둘 이상의 데이터 저장도 가능하다
TreeMap <K, V>
NavigableSet set = treeMap.navigableKeySet();
set.iterator() : 오름차순
set.descendingIterator() : 내림차순
생성 방법
- Thread를 상속
- Runnable Interface 구현
동기화
- Synchronized 키워드
- 동기화 메서드보다 동기화 블록이 효율적이다. (부분 적용이 가능하므로)
실행 순서의 동기화
- Object 클래스에 정의된 메서드를 이용
- NewsReader 사용자 스레드는 getTodayNews() 메서드를 선언,
- 오늘뉴스가 도착했는지 확인해서 false면 wait()한다.
- NewPapaer에서 setTodayNews 메서드를 호출, 메서드 안에서 notifyAll() 호출
- 하단의 메서드들은 민감한 메서드들이므로 모두 동기화 블록 처리해서 실행한다
wait() // 기다린다
notify() // 하나의 스레드만 깨운다
notifyAll() //모든 스레드를 깨운다.
Statement
- 정적 SQL 문을 실행 해, 작성된 결과를 돌려주기 위해 사용하는 객체이다.
- 기본적으로, Statement 객체 당 하나의 ResultSet 객체가 동시에 열릴 수 있다(사용될 수 있다).
- 그러므로 하나의 ResultSet 오브젝트의 읽기가 다른 read에 의해 끼어들어지면, 각각은 다른 Statement 객체에 의해 생성되어 있어야 한다.
- 만약 열려있는(사용 중인) Statement의 ResultSet이 있다면 암시적으로 닫힐 수 있다
(이 말은 ResultSet을 닫으면 Statement객체 또한 암시적으로 자원 해제될 수 있다는 의미인 것 같다)
생각정리
Statement 객체는 Escape의 기능이 없다. 매 요청마다 새로운 Query를 만들어서 실행하는 방식인 것이고, 매번 동적으로 바뀌는 부분을 “select 데이터 from table where id =”+숫자와 같이 스트링을 더하는 형태로 만들 수밖에 없다. 이렇게 생성되는 쿼리는 매 요청마다 새로 만들어지는 것이다 또한 Statement 방식은 유저의 입력 String을 그대로 사용하는 경우가 많으므로 SQL Injection의 위험이 있으므로 사용하지 않는 게 좋겠다
다음은 API에 정의된 원문 내용이다
public interface Statement extends Wrapper, AutoCloseable
The object used for executing a static SQL statement and returning the results it produces.
By default, only one ResultSet object per Statement object can be open at the same time. Therefore, if the reading of one ResultSet object is interleaved with the reading of another, each must have been generated by different Statement objects. All execution methods in the Statement interface implicitly close a statement’s current ResultSet object if an open one exists.
PreparedStatement
- precompiled SQL 문을 나타내는 객체이다.
- SQL 문은 프리 컴파일 해, PreparedStatement 객체에 저장된다.
- 문장을 여러 차례 효율적으로 실행하기 위해 사용될 수 있다.
다음은 API에 정의된 원문 내용이다
public interface PreparedStatement extends Statement
An object that represents a precompiled SQL statement.
A SQL statement is precompiled and stored in a PreparedStatement object.
This object can then be used to efficiently execute this statement multiple times.
Note: The setter methods (setShort, setString, and so on) for setting IN parameter values must specify types that are compatible with the defined SQL type of the input parameter.
For instance, if the IN parameter has SQL type INTEGER, then the method setIntshouldbe used.
If arbitrary parameter type conversions are required, the method setObject should be used with a target SQL type.
In the following example of setting a parameter, con represents an active connection: PreparedStatement pstmt = con.prepareStatement("UPDATE EMPLOYEES SET SALARY =? WHERE ID =?");pstmt.setBigDecimal(1, 153833.00) pstmt.setInt(2, 110592)
CallableStatement
- 스토어도 프로시저 SQL을 실행하기 위한 인터페이스.
- 일반적인 RDBMS을 호출하는 방식과 동일하게 escape 문법을 사용할 수 있다.
- 프로시저 호출 결과에 대한 결괏값을 가져오기 위해서는 OUT Parameter로 result Parameter를 설정해야 한다.
- 일반적인 파라미터는 IN, OUT Parameter를 구분 없이 사용할 수 있다. 첫 번째 파라미터는 1로 설정된다
다음은 API에 정의된 원문 내용이다
public interface CallableStatement extends PreparedStatement
The interface used to execute SQL stored procedures. The JDBC API provides a stored procedure SQL escape syntax that allows stored procedures to be called in a standard way for all RDBMSs. This escape syntax has one form that includes a result parameter and one that does not. If used, the result parameter must be registered as an OUT parameter. The other parameters can be used for input, output or both. Parameters are referred to sequentially, by number, with the first parameter being 1.
{?= call [(,,...)]}
{call [(,,...)]} IN parameter values are set using the set methods inherited from PreparedStatement. The type of all OUT parameters must be registered prior to executing the stored procedure; their values are retrieved after execution via the get methods provided here.
A CallableStatement can return one ResultSet object or multiple ResultSet objects. Multiple ResultSet objects are handled using operations inherited from Statement.
For maximum portability, a call's ResultSet objects and update counts should be processed prior to getting the values of output parameters.
Reference : http://stophyun.tistory.com/37
Reference : http://huelet.tistory.com/entry/JVM-메모리 구조
왜 JVM을 이해해야 하는가?
정보시스템의 설계 및 개발단계의 오류로 인한 성능 저하 문제가 약 33% (설계오류, 아키텍처 오류, 애플리케이션 코드 오류)를 차지하고 있으며 특히, 설계 또는 아키텍처의 오류는 개선에 따르는 비용과 시간이 타 부분에 비하여 막대하므로 정보시스템 구축 시 프로젝트 전 단계에 걸쳐 지속적으로 성능관리를 수행하고 그 결과를 검증하는 것이 중요하다.
같은 기능의 프로그램이더라도 메모리 관리에 따라 성능이 다르게 나타난다
속도 저하 현상이나 예기치 않은 에러 현상 등을 방지하기 위해
한정된 메모리를 효율적으로 사용하여 최고의 성능을 제공하기 위해
JVM 정의
자바 가상 머신 (JVM; Java Virtual Machine)은 우리가 작성한 Java 프로그램, WAS (;Web Application Server) 등을 구별하지 않고 Java 프로그램의 범주에 들어가는 모든 것들을 실행시키는 역할을 한다.
JVM은 정의된 Specification을 구현한 하나의 독자적인 Runtime Instance라고 할 수 있다.
JVM의 특징
특징 1. 스택 기반의 가상 머신
특징 2. 가비지 컬렉션
특징 3. 플랫폼에 독립적
JVM의 기본적인 수행과정
Java Source(. java) - Java Compiler - Java Byte Code(. class) - JVM
- Class Loader System을 통해 Class 파일들을 JVM으로 로딩한다
- 로딩된 Class 파일들은 Execution Engine을 통해 해석된다
- 해석된 프로그램은 Runtime Data Areas에 배치되어 실질적인 수행이 이루어지게 된다. 이러한 실행 과정 속에서 JVM은 필요에 따라 Thread Synchronization과 Garbage Collection 같은 관리 작업을 수행하게 된다
JVM 구성
- Class Loader
- Execution Engine
- Runtime Data Areas
Class Loader
JVM 안으로 Class를 Load 하고 Link를 통해 적절히 배치하는 일력의 작업을 수행하는 모듈. Runtime시에 동적으로 Class를 Load 함
Execution Engine
클래스 로더를 통해 JVM 내의 런타임 데이터 영역에 배치된 바이트코드는 실행 엔진에 의해 실행된다. 실행 엔진은 자바 바이트코드를 명령어 단위로 읽어서 실행한다
Runtime Data Area
JVM이라는 프로그램이 운영체제 위에서 실행되면서 할당받는 메모리 영역이다. 런타임 데이터 영역은 5개의 영역으로 나눌 수 있다
Runtime Data Area
1.Class Area (클래스)
Method Area, Code Area, Static Area로 불리어진다
모든 스레드가 공유되는 영역으로 JVM이 시작될 때 생성된다
1-1. Field Information : 멤버 변수의 이름, 데이터 타입, 접근 제어자에 대한 정보
1-2. Method Information : 메서드의 이름, 리턴 타입, 매개변수, 접근 제어자에 대한 정보
1-3. Type Information : Type 속성이 Class인지 Interface인지의 여부 저장
- Type의 전체 이름 (패키 지명 + 클래스명)
- Type의 Super Class의 전체 이름
- 접근 제어자 및 연관된 interface의 전체 리스트 저장
1-4. Constant Pool
- Type에서 사용된 상수를 저장하는 곳(중복이 있을 시 기존 상수 사용)
- Type에서 사용된 상수를 저장하는 곳(중복이 있을 시 기존 상수 사용)
1-5.Class Variable : 모든 객체가 공유할 수 있고, 객체 생성 없이 접근 가능
2.Stack Area (스택)
JVM 스택은 각 스레드마다 하나씩 존재하며 스레드가 시작될 때 생성된다. 스택 프레임(Stack Frame)이라는 구조체를 저장하는 스택으로, JVM 스택에 스택 프레임을 추가하고(push) 제거하는(pop) 동작만 수행한다
메서드 안에서 사용되어지는 값들 저장, 호출된 메서드의 매개변수, 지역변수, 리턴 값 및 연산 시 일어나는 값들을 임시로 저장
메서드 수행이 끝나면 프레임별로 삭제
3.Heap Area (힙)
new 연산자로 생성된 객체와 배열을 저장하는 공간
클래스 영역에 로드된 클래스만 생성 가능
Garbage Collector를 통해 메모리 반환 JVM 성능 등의 이슈에서 가장 많이 언급되는 공간이다
3-1. Permanent Generation : 생성된 객체들의 정보의 주소 값이 저장된 공간
3-2. Young Generation (New Area)
- Eden : 객체들이 최초로 생성되는 공간
- Survivor : Eden에서 참조되는 객체들이 저장되는 공간
3-3. Old Generationr (Old Area)
- New Area에서 일정 시간 이상 참조되고 있는 객체들이 저장되는 공간
4.Native Method Stack Area (네이티브 메서드)
자바 외에 다른 언어에서 제공되는 메서드들이 저장되는 공간
Java 외의 언어로 작성된 프로그램, API 툴킷 등과의 통합을 쉽게 하기 위하여 JNI (Java Native Interface)라는 표준 규약을 제공, 다시 말해 Native Code로 되어 있는 Function의 호출을 Java 프로그램 내에서 직접 수행할 수도 있고 그 결과 값을 받아 올 수도 있게 된 것이다.
5.PC Register (PC 레지스터)
Thread가 만들어질 때마다 생성되는 공간
Thread가 어떤 부분을 어떤 명령으로 실행할 지에 대한 기록
현재 실행되는 부분의 명령과 주소를 저장
참조되지 않은 객체들을 탐색 후 삭제
삭제된 객체의 메모리를 반환
Heap 메모리의 재사용
Minor Garbage Collection
- New 영역에서 일어나는 Garbage Collection
- Eden 영역에 객체가 가득 차게 되면 첫 번째 Garbage Collection 발생
- Survivor1 영역에 값 복사
- Survivor1 영역을 제외한 나머지 영역의 객체들을 삭제
- Eden 영역과 Survivor1 영역의 메모리가 기준치 이상일 경우, Eden 영역에 생성된 객체와 Survivor1 영역에 있는 객체 중 참조되고 있는 객체가 있는지 검사
- Survivor2 영역을 제외한 영역의 객체들을 삭제
- 반복
Major Garbage Collection (Full Garbage Collection, Stop the world)
- Old 영역에 있는 모든 객체들을 검사
- 참조되지 않은 객체들을 한꺼번에 삭제
- Minor Garbage Collection에 비해 시간이 오래 걸리고 실행 중 프로세스가 정지