객체를 만들 때 인스턴스 필드와 메소드 모두 또는 인스턴스 필드에만 새로운 메모리가 할당됩니다.


14

다음 수업이 있습니다

class Student{

int rollNumber;
int marks;

public void setResult(int rollNumber, int marks){

    this.rollNumber=rollNumber;
    this.marks=marks;   
}

public void displayResult(){

    System.out.println("Roll Number= "+this.rollNumber+"   Marks= "+this.marks);

}
}

이제 다음과 같이 Student 유형의 두 개체를 만듭니다.

Student s1=new Student();
Student s2=new Student();

이제 두 개의 서로 다른 메모리 세트가 인스턴스 필드에 할당됩니다. 이제 내 질문은 메모리가 메소드 ( setResultdisplayResult)에 두 번 또는 한 번 할당되는지 여부입니다 .

다음 그림을 참조하여 어떤 그림이 올바른 정보를 제공하는지 알려주십시오.

여기에 이미지 설명을 입력하십시오


1
귀하의 연구를 공유하면 모든 사람을 도울 수 있습니다. 당신이 무엇을 시도했고 왜 그것이 당신의 요구를 충족시키지 못했는지 알려주십시오. 이것은 당신이 시간을내어 자신을 돕기 위해 노력했고, 명백한 답변을 되풀이하는 것을 막아 주며, 무엇보다도 더 구체적이고 관련있는 답변을 얻는 데 도움이됩니다. 또한 물어
gnat

3
나는 자바를 배우고 있습니다 ... 그리고 모든 자료에서 그들은 객체를 만들 때마다 모든 인스턴스 필드에 새로운 메모리가 할당된다고 말합니다. 그러나, 어떤 자료도 신선한 메모리가 메소드에 할당 될지 또는 아닙니다
Harish_N

답변:


13

메소드 코드는 Class(더 간결하게 Class<Student>) 의 일부이며 클래스가 처음로드 될 때 메모리에로드됩니다.

즉, 메소드를 실행할 때 추가 메모리가 사용되어 매개 변수, 로컬 변수, 임시 표현식 결과, 반환 값 등에 메모리를 할당합니다. 그러나 이러한 메모리는 스택에 할당됩니다 (새 인스턴스를 만들 때 사용되는 메모리 는 힙에 할당됩니다) .

귀하의 질문에 따라 이제 그림 B가 정확하다는 것이 분명해야합니다 (실제로 메소드를 호출 할 때 발생하는 일을 반영하지는 않습니다).


확인. 나는 지금 90 % 명확하다 ....하지만 약간의 의심이있다. Student 타입의 10 개의 객체를 생성한다면, 1 개의 새로운 메모리 세트 만 Student 클래스에 존재하는 메소드에 할당되고 10 개의 새로운 메모리 세트는 10 개의 객체에 대한 인스턴스 변수를 저장하도록 할당되었습니다.
Harish_N

권리. 메모리를 취하는 속성 일뿐 아니라 인스턴스 자체와 관련된 작은 오버 헤드가 있다고 생각하십시오 (속성이없는 클래스의 인스턴스는 0 바이트 이상의 메모리를 사용합니다).
SJuan76

한가지 더 ... 나는 자바를 염두에두고 질문을했다. ... 똑같은 일이 자바에서도 일어난다 .....
Harish_N

Java 언어 사양에서는 언제 어떤 목적으로 할당되는 메모리 양에 대해서는 언급하지 않습니다. 그것은 구현 자에게 맡겨져 있으며, 모든 구현자는 다르게 선택할 수 있습니다.
Jörg W Mittag

6

인스턴스 필드 (속성 백업 필드 포함)는 N- 개체에 대한 N 개 사본을 가져옵니다.

정적 필드는 클래스 당 하나의 사본을 얻습니다.

메소드는 프로그램 "이미지"또는 실행 코드 세그먼트의 일부인 바이트 코드 블록 (또는 JIT 이후의 고유 명령어 블록)입니다. 메소드는 디스크에있을 때 이미 프로그램 이미지의 일부입니다. 이미지가 OS (또는 CLR)에 의해로드되면 메소드 코드의 단일 공유 사본이 있습니다.

호스트 가능한 컴파일러를 사용하여 새 메소드를 즉시 컴파일 할 수있는 경우를 제외하고는 일반적으로 "힙"또는 런타임 할당의 일부가 아닙니다. 메소드는 오브젝트와 같이 "할당"되지 않으며 오브젝트 작성에 대해 "할당"되지 않습니다. 그것들은 단일 객체가 인스턴스화되기 전에 단지 프로그램의 일부로 존재합니다. 람다 / 델리게이트조차도 즉시 할당되지 않습니다. 컴파일러는 동적으로 보이는 이러한 다른 코드 객체를 구현하기 위해 주문형 클래스를 만들고 디스크의 바이트 코드 이미지의 일부로도 존재합니다.

댓글 당 업데이트 :

JVM 표준은 다음과 같이 말합니다.

2.5.4. 방법 영역

Java Virtual Machine에는 모든 Java Virtual Machine 스레드간에 공유되는 메소드 영역이 있습니다. 방법 영역은 기존 언어의 컴파일 된 코드를위한 저장 영역과 유사하거나 운영 체제 프로세스의 "텍스트"세그먼트와 유사합니다. 런타임 상수 풀, 필드 및 메소드 데이터와 같은 클래스 별 구조와 클래스 및 인스턴스 초기화 및 인터페이스 초기화에 사용되는 특수 메소드 (§2.9)를 포함한 메소드 및 생성자 코드를 저장합니다.

메소드 영역은 가상 머신 시작시 작성됩니다. 메소드 영역은 논리적으로 힙의 일부이지만 간단한 구현에서는 가비지 수집 또는 압축을 선택하지 않을 수 있습니다. 이 버전의 Java Virtual Machine 사양에는 메소드 영역의 위치 나 컴파일 된 코드를 관리하는 데 사용되는 정책이 필요하지 않습니다. 방법 영역은 고정 된 크기 일 수 있거나 계산에 의해 요구되는대로 확장 될 수 있고, 더 큰 방법 영역이 불필요 해지면 수축 될 수있다. 메소드 영역의 메모리는 연속적 일 필요는 없습니다.

따라서 (1) 예가이 작업을 수행하는 방법을 지시하지는 않지만 (2) 기존 언어의 컴파일 된 코드, 즉 저장 영역과 유사하다는 것이 분명합니다. 텍스트 세그먼트 이것이 내가 만드는 요점입니다.


당신이 말하는 것은 말이되지만 JLS에 의해 실제로 보장됩니까? 일반적으로 JLS는 구현 자들에게 이와 같은 질문에 많은 여유를줍니다.
Jörg W Mittag

그 시점에서 확실하지 않습니다, @ JörgWMittag. 당신이 옳을 수도 있습니다. 내가 만들려고 한 것은 "new T ()"는 메소드의 새로운 인스턴스를 할당하지 않는다는 것입니다. JVM의 특성에 따라 클래스 로더는 실제로 바이트 코드를 힙에 저장하므로 클래스 자체가 인스턴스화되고 가비지 수집되는 시나리오가있을 수 있습니다. 그러나 그것은 런타임의 구현 세부 사항이며 개념적으로 내가 말하는 힙은 "사용자"힙입니다. 클래스 및 메소드는 일반 사용자 컨텍스트에서 데이터로 간주되지 않습니다. 그러나 우리는 userland에서 클래스 로더를 제어 할 수 있기 때문에 모르겠습니다.
codenheim

JLS는 힙에 대해 전혀 이야기하지 않습니다. 유한 한 고정 크기 스택 및 동적 힙 대신 힙이없는 동적 스택으로 Java를 구현하는 것이 합법적입니다. JLS는 또한 JVM에 대해 아무 말도하지 않으며 JVM없이 Java를 구현하는 것이 완벽하게 유효합니다.
Jörg W Mittag

JLS를 참조하고 있지만 JVM과 대화하고 있습니다. JVM 표준은 확실히 힙에 대해 설명합니다. 스택의 로컬 범위를 벗어나는 변수 범위 / 수명을 제공해야합니다. 이론적으로 가능한 것은 "알려진 구현"이라는 관점에서 생각하는 것을 선호합니다. JVM이 순수한 스택 머신이 아니기 때문에 힙 프리미티브없이 전체 JVM을 구현하는 것은 힘들거나 불가능한 작업입니다. Forth 머신 및 기타 순수한 스택 아키텍처에 대한 나의 이해는 임의의 변수 액세스에 대한 기본 요소가 존재하는 경우 가능할 수 있지만, 보지 못했습니다.
codenheim

@ JörgWMittag-토론에 관심이있을만한 것을 답변에 추가했습니다. 요점은 기존 런타임 시스템의 기존 코드 또는 텍스트 세그먼트와 유사하다는 것입니다.
codenheim

-4

객체가 할당 될 때 객체가 파괴 될 때 모든 인스턴스 변수에 대한 슬롯이 생성되고 파괴됩니다. 따라서 인스턴스 변수도 힙 메모리에 할당됩니다. 로컬 변수는 메소드가 호출됩니다.


1
이것은 이전 답변에서 제공된 정보를 반복하는 것으로 보입니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.