DEV/JAVA

String에 대하여...

wooki4307 2021. 7. 17. 18:21

1차 면접을 봤었다.

 

면접진행 중 나를 당황스럽게 하는 질문이 몇가지가 있었는데 면접이후 이거에 대해 심도있게 확인해본 경험이 없어 이제 같이 확인을 하고 잊지 않기 위해 적고, 남기려고 한다.

 

첫번째

String a = "abc";

String b = "abc";

String c = new String("abc");

 

위와 같이 사용했을때의 차이가 있는지에 대해 질문하는 사항이었다.

 

처음 질문 받았을땐 어버버하고 답을 못하였지만 면접이후 불현듯 생각나더라...

 

JVM메모리구조...

 

Java를 실행하면 메모리를 어떻게 사용할까...? 를 알아보고 있다면 개구리책을... 모른다면 개구리책을 추천한다.

 

먼저 다음과 같은 소스코드가 있다고 해보자.

 

클래스파일을 생성하면 import되는 패키지도 있고, 메소드가 있고, 또 거기에 사용하는 여러 변수들이 존재한다.

 

import java.util.Scanner;

public class QuestionFirst {

    public static void main(String[] args){
        String a = "abc";
        String b = "abc";
        String c = new String("abc");
        System.out.println(a);
        System.out.println(b);
        System.out.println(c);
    }
}

실행결과는 예상하듯이 나온다.

 

abc

abc

abc

 

그러면 차이가 없는거 아니냐? 하겠지만...

 

있다!!!!

 

위의 예로든 소스는 사용범위가 극히 제한되지만 JVM은 메모리를 사용한다.

 

JVM의 메모리는 크게 3가지의 구조로 가지고 있다.

 

스태틱영역, 스택영역, 힙영역으로 나뉜다.

 

스태틱영역의 경우 JVM이 시작될때 사용할 패키지(import된 것들)과 String의 기본인 java.lang이 기본적으로 올라가서 어디서든 쓸 수 있도록 환경을 만들어 놓는다.

 

그러면 "그래, 스태틱은 그런 영역으로 사용되는데 스택이랑, 힙은 뭔데??"

 

스택은 위의 예시에 적혀있는 main(String[] args) 안의 전체 영역이 스택의 영역이 된다.

 

변수 a, b모두 스택영역에서 사용되는데 a,b 변수가 가지고 있는 값은 heap영역에 pointer처럼 관리가 된다.

 

그렇다면 여기서 본론인 a,b의 차이는?

 

java에서 String에 대한 heap영역은 한군데가 존재한다. 

 

Heap영역의 "String Constants Pool"

 

String의 경우 특별한 Heap영역을 참조한다.

 

따라서, 변수 a,b는 같은 인스턴스 내에서 관리되는 반면, c의 경우에는 특별한 인스턴스를 참조하여 관리된다는 것이다.

 

위의 소스코드를 변형시켜 값이 서로 같은지 확인해보면 값이 다르다는 것을 알 수 있다.

public class QuestionFirst {

    public static void main(String[] args){
        String a = "abc";
        String b = "abc";
        String c = new String("abc");
        if (a == b) {
            System.out.println("a,b 같음");
        } else {
            System.out.println("a,b 다름");
        }

        if (a == c) {
            System.out.println("a,c같음");
        } else {
            System.out.println("a,c 다름");
        }

        if (b == c) {
            System.out.println("b,c같음");
        } else {
            System.out.println("b,c 다름");
        }
    }
 }

결과값은

 

조금 길었는데 저 질문은 다음과 같은 내용을 아는지 물어보는 것으로 예상이 된다.

 

1. JVM의 메모리 구조가 Static, Stack, Heap으로 이루어져 있는걸 아는지?

2. 그렇다면 저위의 인스턴스 개수는 몇개가 생성이 되는지?

3. String에 대해 특별한 Heap영역이 있는걸 알고 있는지?

 

지금 나의 답변은 이거였을거다.

 

a,b,c모두 같은 값으로 표현이 되지만 해당 인스턴스 자체가 다릅니다. String의 경우 인스턴스는 Heap영역에 String Constants Pool에서 생성되고 저장이 된다. 한마디로 같은 인스턴스 지만, c의 경우 Heap영역안에 별도의 인스턴스로 존재한다. 따라서 a와 b는 같고, c는 다른값으로 표현된다. 덧붙여 말하면 c의 경우 메모리의 낭비가 심해질 수 있다.

면접덕에 하나 더 배워가는 것 같다.

 

추가 기억에 남는 질문은 다음에 계속 적어보겠습니다.

 

참조

책: 스프링 입문을 위한 자바 객체지향의 원리와 이해

URL: https://www.journaldev.com/797/what-is-java-string-pool