본문 바로가기

언어/Java

자바의 메모리 모델, Object 클래스

자바 가상머신의 메모리 모델

 

자바 프로그램은 자바 가상머신 위에서 실행되며 자바 가상머신은 운영체제 위에서 실행된다

운영체제가 메인 메모리 공간을 할당해준다

* 메인 메모리 : 프로그램 실행에 필요한 메모리 공간 → 물리적으로 램 ( RAM )이라 한다

 

자바 가상머신의 메모리 공간 나눔

  1. 메소드 영역

      = 특정 클래스의 정보가 메모리 공간에 올려질 때 채워지는 영역

         메소드의 바이트코드, static 변수

  * 바이트코드 : 자바 가상머신에 의해 실행이 가능한 코드

  인스턴스의 생성 혹은 클래스 변수 접근을 위해 메소드에 클래스 정보를 저장해야 한다

 

  2. 스택 영역

      = 중괄호( 메소드 ) 를 벗어나면 바로 소멸되는 특징의 데이터를 저장

         지역변수, 매개변수

  main 메소드에서 Run 메소드를 호출하여 스택에 지역변수 num과 return된 결과값이 저장된다  return이 반환된 메소드는 종료되었기에 스택에서 소멸된다

 

  3. 힙 영역

      = 변수와 달리 인스턴스는 소멸시점, 방법이 달라 따로 힙 영역에 보관한다

         인스턴스

         인스턴스 소멸 : 더이상 접근 할 수없는 아무런 참조도 하지 않는 상태일 때 소멸됨 ( 가비지 컬렉션 )

 

 

 

Object 클래스

 

finalize 메소드 : 가비지 컬렉션이 되기 전에 자동으로 호출되는 메소드

                          → 인스턴스 소멸 시 실행해야할 코드가 있으면 finalize 메소드를 오버라이딩 하면 됨

@Override
protected void finalize() throws Throwable{
    ...
}

가비지 컬렉션은 빈번하지 않기 때문에 실행되지 않을 수도 있다가비지 컬렉션 요청 방법 : system.gc() → 요청이기에 확실히 실행되지는 않는다

 

equals 메소드 : 인스턴스끼리 비교할 때 안에 내용이 아닌 참조값을 비교하기에 안에 내용을 비교하고 싶을 때 사용한다

@Override
public boolean equals(Object obj) {
    if (this.num ==((makeNum)obj).num)
        return true;
    else
        return false;
}

 

clone 메소드 : 인스턴스를 복사하고, 그 만들어진 복사본의 참조 값이 반환 될 수 있다

                        → 인터페이스 ( Cloneable ) 를 구현한 인스턴스를 대상으로만 메소드를 호출할 수 있다

* Cloneable : 마커 인터페이스로 복사를 해도 된다는 표식의 인터페이스

class point implements Cloneable{
	
	@Override
	public Object clone() throws CloneNotSupportedException{
		return super.clone();
	}
}

복사 실패시 CloneNotSupportedException로 리턴

 

class point {
	int num;
	
	public point(int num) {
		this.num = num;
	}

	public void change(int num) {
		this.num = num;
	}
	
}

class REpoint implements Cloneable{
	
	point n ;
	
	public REpoint(int num) {
		n = new point(num);
	}
	
	public void REchange(int num) {
		n.change(num);
	}
	
	public void show () {
		System.out.println(n.num);
	}
	
	@Override
	public Object clone() throws CloneNotSupportedException{
		return super.clone();
	}
}

public class Cloneable_M {
	public static void main(String[] arg) {
		REpoint p = new REpoint(1);
		REpoint p2;
		
		try {
			p2 = (REpoint)p.clone();
			p.REchange(3);
			p.show();
			p2.show();
			
		}catch(CloneNotSupportedException e){
			e.printStackTrace();
			
		}

	}
}

복사할 때 새로운 인스턴스를 생성하지 않아서 원본과 복사본과 인스턴스를 공유하게 된다

참조변수가 지니는 참조 값이 그대로 새 인스턴스에 복사되는 것을 얕은 복사라고 한다

 

참조하는 Point 인스턴스까지 복사가 이뤄지려면 ( 깊은 복사 )

class point implements Cloneable{
	int num;
	
	public point(int num) {
		this.num = num;
	}

	public void change(int num) {
		this.num = num;
	}
	
	@Override
	public Object clone() throws CloneNotSupportedException{
		return super.clone();
	}
}

class REpoint implements Cloneable{
	
	point n ;
	
	public REpoint(int num) {
		n = new point(num);
	}
	
	public void REchange(int num) {
		n.change(num);
	}
	
	public void show () {
		System.out.println(n.num);
	}
	
	@Override
	public Object clone() throws CloneNotSupportedException{
		REpoint copy = (REpoint)super.clone();
		copy.n = (point)n.clone();
		
		return copy;
	}
}

public class Cloneable_M {
	public static void main(String[] arg) {
		REpoint p = new REpoint(1);
		REpoint p2;
		
		try {
			p2 = (REpoint)p.clone();
			p.REchange(3);
			p.show();
			p2.show();
			
		}catch(CloneNotSupportedException e){
			e.printStackTrace();
			
		}

	}
}

point의 인스턴스를 생성할 때 참조 값이 p2의 num을 바라보게 해야된다

 

참고) 에러 : java.lang.CloneNotSupportedException

clone() 호출 객체에 implements Cloneable가 없어서 오류가 나는 것

'언어 > Java' 카테고리의 다른 글

Arrays 클래스  (0) 2023.01.21
래퍼 클래스, BigInteger 클래스  (1) 2023.01.20
인터페이스, 추상 클래스  (0) 2022.06.26
클래스 상속, 오버라이딩  (0) 2022.06.26
메소드 오버로딩, String 클래스  (0) 2022.06.25