해결된 질문
작성
·
257
1
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.
1. 강의 내용과 관련된 질문을 남겨주세요.
2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.
(자주 하는 질문 링크: https://bit.ly/3fX6ygx)
3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.
(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)
질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.
=========================================
[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? (예/아니오)
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)
3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)
[질문 내용]
배열을 생성할때 int[] students1 = {90, 80, 70, 60, 50}; 이러한 형식이 있다면 {90, 80, 70, 60, 50}이 부분은 힙 영역에 생성되고 int[] students1 이 부분은 스택 영역에 생성되서 스택에 있는 레퍼런스값으로 힙 영역 메모리에 접근한다고 이해 했습니다. 근데 이 부분을 테스트 하던 도중 주소 값라고 말해주신 [I@b4c966a 이러한 부분이 매 실행마다 바뀌지 않았다는 것 입니다. c언어를 공부 했을때는 매번 주소값이 바뀌었는데 java에서 찍어보니 매 실행마다 같은 값이 나오는걸 확인했습니다. 배열의 길이를 바꿔서 찍어보고, 할당 순서도 바꿔봤는데도 같은 값이 나와서 따로 찾아보니깐 hash코드의 값이라는 말이 있어서 https://varoa.net/jvm/java/openjdk/biased-locking/2017/01/30/hashCode.html 이곳에서 찾아보니 이런 말이 있어서 더 헷갈립니다. cs랑 자바에 관해 지식이 부족해서 잘 이해 했을지는 모르겠지만 [I@b4c966a 이게 hash코드로 만들어진거고, 그 hash코드는 메모리 주소랑 상관이 없는건가요? 지금 대체 저 [I@b4c966a 값이 어떻게 만들어진거고, 왜 타입, 자료형, 크기, 선언 순서를 바꿔도 이 값은 변하지 않는건가요
답변 2
2
안녕하세요. 이현준님
이 부분을 제대로 이해하려면 사실 2가지 개념을 알아야 합니다.
1. 자바의 메모리 참조
우선 반복 실행해도 코드가 같고, 자바 환경이 같으면, 같은 메모리의 참조가 출력될 가능성이 있습니다.
자바의 경우 컴퓨터 내부의 메모리의 주소를 그대로 사용하는 것이 아니라 내부에서 메모리 표를 생성한 다음에 자바의 메모리 영역과 PC의 메모리 영역을 매핑하는 작업을 합니다. 우리가 보는 참조값은 자바에서 사용하는 메모리 표에 적힌 번호인 것이지요. 우리가 실제 PC 메모리의 주소를 볼 수는 없습니다.
따라서 같은 환경에서 동일하게 실행하면 자바에서 메모리 표의 같은 위치를 사용할 가능성이 있습니다.
같은 배열을 두 번 만들어서 실행해보면 다른 참조값이 출력되는 것을 확인할 수 있습니다.
public class HelloTest {
public static void main(String[] args) {
int[] students1 = {90, 80, 70, 60, 50};
int[] students2 = {90, 80, 70, 60, 50};
System.out.println("students1 = " + students1);
System.out.println("students2 = " + students2);
}
}
실행 결과
students1 = [I@251a69d7
students2 = [I@6b95977
2. 자바의 hashCode()
자바의 hashCode()를 제대로 이해하려면 해시 테이블과 해시 알고리즘에 대해서 먼저 이해해야 합니다. 이 부분은 자바 중급2편에서 자세히 설명드립니다 🙂
감사합니다.
0
안녕하세요, 인프런 AI 인턴입니다.
이현준님의 질문은 자바 배열의 메모리 할당 방식과 출력되는 참조값(하시코드)의 의미에 대한 것으로 이해됩니다. 자바에서 배열이나 객체의 참조값을 출력할 때 나타나는 [I@b4c966a
와 같은 형식은 실제 메모리 주소를 직접적으로 나타내는 것이 아닌, hashCode
를 바탕으로 한 표현입니다. 이 값은 자바 가상 머신(JVM)이 객체를 구별하기 위해 사용하는 값으로, 해시코드입니다. 이는 객체의 실제 메모리 주소와는 다르며, 같은 실행에서는 동일한 값을 유지하지만 다른 실행에서는 다를 수 있습니다. 동일한 실행 환경에서 같은 값이 나오는 것을 봤을 때, 어떤 경우에는 JVM이 동일한 해시코드를 사용할 수 있기 때문입니다.
이와 관련해 기본형과 참조형의 메모리 할당 방식의 차이와, Java에서 객체의 hashCode가 어떻게 사용되는지에 대해 이해할 수 있는 기존 질문의 답변 링크를 나누고자 합니다.
첫 번째 링크에서는 기본형과 참조형의 차이에 대해 설명하고 있으며, 기본형(int, long 등)은 값 자체를 저장하지만 참조형(배열, 객체 등)은 메모리의 참조값(주소)을 저장한다고 설명합니다.
두 번째 링크에서는 참조형의 메모리 할당 방식과 hashCode
에 대한 궁금증을 해결할 수 있는 질문과 답변이 포함되어 있습니다. 특히, 자바에서 hashCode()
메서드의 사용과 참조값의 의미에 대해 더 깊이 이해할 수 있을 것입니다.
자바에서 표현되는 참조값의 해시코드는 객체의 실제 물리 메모리 주소와 직접적인 연결이 없으며, JVM이 객체를 식별하기 위해 내부적으로 사용하는 값입니다. 따라서 동일한 객체라도 실행 환경이나 조건에 따라 다른 해시코드를 가질 수 있습니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.
그 JVM이 객체를 식별하기 위해 내부적으로 사용하는 값은 HashCode는 무엇을 기준으로 만들어진건가요? 강의 내용을 볼때 주소값이라고 했는데 이미지로 추가했던 자료를 봐보시면 주소값과는 상관없다고 하더라고요, 그렇다면 자바에선 JVM만이 그 HashCode라는 걸로 분류한 실제 스택에 쌓인 레퍼런스 값은 볼수 없는건가요? JVM이 왜 주소값 사용이 아닌 HashCode라는 개념을 도입했는지도 궁금하네요 추가로 "동일한 실행 환경에서 같은 값이 나오는 것을 봤을 때, 어떤 경우에는 JVM이 동일한 해시코드를 사용할 수 있기 때문입니다." 이 부분을 조금 더 자세히 설명해주면 좋을 것 같습니다.