본문 바로가기
Web

[Java] 자바의 메모리 사용 구조

by DuncanKim 2022. 6. 27.
728x90

[Java] 자바의 클래스와 메모리 사용 구조

자바는 메모리를 관리해준다. Garbage Collector가 개발자가 만들어놓고 사용하지 않는 객체들을 수거하고 stack은 변수가 들어왔다 나갔다 하면서 stackoverflow가 일어나지 않게 만들어준다.

 

그렇지만, 내가 만든 변수가 어디에 저장되고 어떤 식으로 동작을 하는지는 알아야 한다.

그래야 컴퓨터의 성능을 최대한 활용하는 프로그램을 만들 수 있으니까.

 

이번 포스팅에서는 아래와 같은 클래스와 변수들이 존재할 때, 자바는 메모리를 어떻게 사용하는 지를 알아본다.

 

상속, 다형성의 개념도 함께 다룰 것이기 때문에, 상속 또는 다형성이 잘 이해가 되지 않는다면, 아래의 이전 글을 참조하는 것이 좋을 것 같다.

 

2022.06.13 - [프로그래밍 언어/Java] - [Java] 상속 inheritance 을 활용한 정보관리 시스템 만들기

 

[Java] 상속 inheritance 을 활용한 정보관리 시스템 만들기

[Java] 상속 inheritance 을 활용한 정보관리 시스템 만들기 상속은 객체 지향에서 중요한 개념이다. 매번 클래스에 같은 내용을 넣지 않고, 기존의 클래스에 추가하고 싶은 내용이 있는데, 각기 다른

masterpiece-programming.tistory.com

 

2022.06.13 - [프로그래밍 언어/Java] - [Java] 다형성(Polymorphism) 알아보기

 

[Java] 다형성(Polymorphism) 알아보기

[Java] 다형성(polymorphism) 알아보기 칼은 참 다양한 종류가 있다. 요리할 때만 해도, 과일칼, 채소자르는 칼, 고기 다지는 칼, 빵칼 등등등.. 요리 용도가 아니라 도축, 수술 등등 많은 곳에서 쓰는

masterpiece-programming.tistory.com

 

 

1. 클래스 설계

 

이해가 되기 쉽도록, Benz 사의 S-Class 자동차를 가상으로 만들어본다고 생각하고 클래스를 만들어 보았다.

먼저 S-Class 자동차를 객체로 만들어 각종 함수를 실행해볼 Main 클래스

그리고 모든 벤츠 자동차 설계의 핵심이 되는 요소를 담고 있는 Benz 클래스,

벤츠 자동차 중에 가상 최상위 모델인 S 클래스에 더 좋은 기능을 탑재하기 위해 Benz 클래스를 상속해서 새로만든 sClass 클래스가 있다.

 

 

1) Benz 클래스

class Benz{
    static String shape = "Metal Aluminum";
    public Benz(){
        String tire = "15인치";
        int maxSpeed = 200;
        String engine = "fossil Fuels";
    }

    public void start(){
        System.out.println("부릉");
    }
}

 

 

Benz 클래스에는 자동차의 기본적인 요소인 타이어, 최고속도,  엔진타입과 관련된 변수들이 기본으로 설정했다.

또한 static으로 자동차 외관의 형상을 메탈 알루미늄으로 설정했다. 

static은 정적 변수로, 이 클래스를 가지고 구현한 객체들이 모두 공통으로 이 변수를 가지게 된다.

만약 이 shape 변수가 바뀐다면, s클래스든, a클래스든 모든 객체의 shape 변수가 바뀌는 것이다.

 

만약 Benz 클래스로 자동차를 만든다면 기본적으로 tire를 15인치로 가지고 최고속도는 200km/h이며, 엔진타입은 화석연료이다.

그리고 기본 함수로 start()라는 void 함수를 가지고 있는데, 만약 Benz 클래스의 객체를 생성해서 함수를 호출하면 "부릉"이 나올 것이다.

 

Main 클래스에서 구현을 하여 확인을 한 번 해보자.

 

public class Main {
    public static void main(String[] args) {
        Benz aClassGasoline = new Benz();
        aClassGasoline.start();
    }
}

// 출력 : 부릉

Benz 타입의 aClassGasoline이라는 이름을 가진 객체가 생성되었다.

aClassGasoline을 활용해서 start() 함수를 호출하면 부릉이라는 출력이 나옴을 알 수 있다.

 

 

 

2) S 클래스 만들기

 

기본 기능 말고 추가기능을 가진 자동차를 만들고 싶으면 어떻게 해야될 까?

바로, 새로운 클래스를 만들면 된다.

 

기존의 벤츠가 가지고 있는 기능을 그대로 담고 있으면서 새로운 기능을 추가할 수도 있고,

기존의 기능을 바꾸어서 새로운 자동차를 만들 수도 있다.

 

자바에서는 extends를 통해 상속을 받을 수 있다. (다만 클래스 다중 상속은 허용하지 않는다.)

 

s클래스가 되었기 때문에, 기본 타이어 값은 19인치, 최고속도는 300으로 향상되었다. 그것을 초기 기본값으로 가지고 있다.

엔진의 경우도 타입을 선택할 수 있는데, 객체를 생성할 때, 가솔린 또는 디젤을 선택하도록 한다.

 

아래 함수들은 get과 set을 활용한 것들로, set은 그 객체에 새로운 변수값을 세팅할 수 있는 것이고,

get은 현재 세팅된 변수의 값을 리턴하는 함수이다.

 

또한 상위 클래스 Benz에는 있는 변수 shape을 뽑아보기 위해서, getShape()라는 함수도 두었다.

현재 sClass 클래스에 shape이란 변수가 없는데, 만들고 실행이 가능할까?

아래 출력에서 상속의 힘을 들여다 보자.

 

맨 아래에 @override 어노테이션이 보이는데, 이것은 S 클래스에서 싸구려 '부릉' 소리가 나면 안되기 때문에

start() 함수를 수정하여 s클래스.start()를 하면 '부르릉' 하면서 고급스러운 소리가 나도록 만들었다.

 

class sClass extends Benz{
    private String tire, engine;
    private int maxSpeed;
    public sClass(String engine) {
        this.tire = "19인치";
        this.maxSpeed = 300;
        this.engine = engine;
    }
    public String getShape(){
        return shape;
    }

    public String getEngine() {
        return engine;
    }

    public String getShape() {
        return shape;
    }
    public String getTire() {
        return tire;
    }

    public void setTire(String tire) {
        this.tire = tire;
    }

    public int getMaxSpeed() {
        return maxSpeed;
    }

    public void setMaxSpeed(int maxSpeed) {
        this.maxSpeed = maxSpeed;
    }

    @Override
    public void start(){
        System.out.println("부르릉");
    }
}

 

getter and setter를 활용하면 위의 함수들을 자동으로 IDE들은 생성을 해준다.

(아래의 설명은 intelliJ 기준! 다른 IDE들도 이와 비슷하게 생성한다)

단, 이것을 생성하려면 클래스 내에 선언된 변수가 있어야 한다. 그렇지 않으면 자동 생성이 되지 않는다.

 

 

 

이렇게 해서 만들어진 클래스를 직접 메인에서 구현을 해서 써보자!

 

 

3) 메인 클래스에서 실행하기

public class Main {
    public static void main(String[] args) {
        sClass sclassDiesel = new sClass("Diesel");
        sClass sclassGasoline = new sClass("galsoline");
        // Sclass 형식의 sclassDiesel의 변수 박스에 Sclass의 인스턴스를 생성하여 담는다.
        // 만약 맨 왼쪽에 int를 쓴다면, sclassDiesel은 int 형태와 호환되지않는(상속도 받지 않았고, 같은 형태도 아니다) 타입이기 때문에
        // 실행시 오류가 난다.

        sclassDiesel.start();
        System.out.println(sclassDiesel.getShape());
        System.out.println(sclassDiesel.getTire());
        System.out.println(sclassGasoline.getEngine());
    }
}

/* 결과
부르릉
Metal Aluminum
19인치
galsoline
*/

sClass 를 새롭게 설계한대로 나오는 것을 알 수 있다.

getShape의 경우, 부모 클래스에서 선언한대로 잘 나온다는 것을 알 수 있다.

 

주석에 써놓은 이야기는 '다형성'과 관련이 되어 있는 것인데, sclassGasoline도 어떻게 보면 하나의 타입이라고 할 수 있다는 이야기를 하는 것이다. sClass의 타입을 우리가 만든 것인데, int에 끼워넣는 다는 것은 불가능하기 때문에 오류가 생긴다고 하는 것이다.

 

만약 맨 왼쪽 타입 자리에 sClass 대신, Benz를 넣는다면 실행이 가능할까?

이것은 가능할 '수도' 있다. '멤버 변수'와 '함수'가 같은 개수, 이름으로 존재한다면.

그렇지만 보통 불가능하다. 위의 코드의 경우, Benz가 'getEngine' 등의 함수를 가지고 있지 않다.

그래서 만약 아래에서 객체를 생성해서 get, set류의 함수를 호출한다면 오류가 발생한다.

 

+ 다형성

한편, Benz 클래스의 객체를 sClass의 변수 안에 담는 것이 가능할까?
가능하다. 물론 sClass에서 구현하고 싶은 엔진명을 부여하는 것이 되지 않긴 하겠지만,
sClass sclassDiesel = new Benz(); 는 생성이 가능하다는 이야기이다.

 

 

4) 전체 코드

public class Main {
    public static void main(String[] args) {
        sClass sclassDiesel = new sClass("Diesel");
        sClass sclassGasoline = new sClass("galsoline");
        // Sclass 형식의 sclassDiesel의 변수 박스에 Sclass의 인스턴스를 생성하여 담는다.
        // 만약 맨 왼쪽에 int를 쓴다면, sclassDiesel은 int 형태와 호환되지않는(상속도 받지 않았고, 같은 형태도 아니다) 타입이기 때문에
        // 실행시 오류가 난다.

        sclassDiesel.start();
        System.out.println(sclassDiesel.getShape());
        System.out.println(sclassDiesel.getTire());
        System.out.println(sclassGasoline.getEngine());
    }
}

class Benz{
    static String shape = "Metal Aluminum";
    public Benz(){
        String tire = "15인치";
        int maxSpeed = 200;
        String engine = "fossil Fuels";
    }

    public void start(){
        System.out.println("부릉");
    }
}

class sClass extends Benz{
    private String tire, engine;
    private int maxSpeed;
    public sClass(String engine) {
        this.tire = "19인치";
        this.maxSpeed = 300;
        this.engine = engine;
    }


    public String getEngine() {
        return engine;
    }

    public String getShape() {
        return shape;
    }
    public String getTire() {
        return tire;
    }

    public void setTire(String tire) {
        this.tire = tire;
    }

    public int getMaxSpeed() {
        return maxSpeed;
    }

    public void setMaxSpeed(int maxSpeed) {
        this.maxSpeed = maxSpeed;
    }

    @Override
    public void start(){
        System.out.println("부르릉");
    }

}

 

 

 

 

2. 자바의 메모리 사용

 

엔진의 이름을 반환하는 함수를 불러올 때,

자바는 어떻게 값을 불러오고 각각의 변수들은 어디에 저장되는 것일까?

 

이런 식으로 분리가 된다.

static 영역, 힙 영역, 스택 영역에 들어가는 것들은 다음과 같다.

static 영역 : 클래스, 메소드, static 변수, 전역 변수
힙 영역 : 객체 
스택 영역 : 지역 변수, 매개 변수 등

 

728x90

'Web' 카테고리의 다른 글

[Java] Error와 Exception, 예외 처리  (0) 2022.06.29
[Java] 인터페이스의 다형성  (0) 2022.06.28
[Java] 클래스 제대로 알아보기  (0) 2022.06.27
[HTML/CSS] Flex 활용방법  (0) 2022.06.26
[HTML/CSS] SPA가 무엇인가?  (0) 2022.06.26

댓글