자바 더미,스 택,메모리 분석

9033 단어 자바
JAVA 에는 6 개의 다른 곳 에서 데 이 터 를 저장 할 수 있 습 니 다.1.레지스터(register).이것 은 다른 저장 소 와 다른 곳 인 프로세서 내부 에 있 기 때문에 가장 빠 른 저장 소 입 니 다.그러나 레지스터 의 수량 이 매우 제한 되 어 있 기 때문에 레지스터 는 컴 파일 러 가 수요 에 따라 분배 한다.직접 제어 할 수도 없고 프로그램 에서 레지스터 가 존재 하 는 흔적 을 느 낄 수도 없다.2.스 택(stack).유 니 버 설 RAM 에 있 지만'스 택 포인터'를 통 해 프로세서 에서 지원 을 받 을 수 있 습 니 다.스 택 포인터 가 아래로 이동 하면 새 메모 리 를 할당 합 니 다.위로 이동 하면 메모리 가 방출 됩 니 다.이것 은 레지스터 에 버 금 가 는 빠 르 고 효과 적 인 배분 저장 방법 이다.프로그램 을 만 들 때 JAVA 컴 파일 러 는 스 택 에 저 장 된 모든 데이터 의 정확 한 크기 와 생명 주 기 를 알 아야 합 니 다.스 택 지침 을 상하 로 이동 할 수 있 도록 메모리 공간 을 만들어 야 하기 때 문 입 니 다.이 제약 은 프로그램의 유연성 을 제한 하기 때문에 일부 JAVA 데 이 터 는 스 택 에 저장 되 어 있 습 니 다.특히 대상 참조 이지 만 JAVA 대상 은 저장 되 지 않 습 니 다.3.쌓다.모든 JAVA 대상 을 저장 하 는 일반적인 메모리 탱크창고 와 다른 장점 은 컴 파 일 러 가 더미 에서 얼마나 많은 저장 구역 을 분배 해 야 하 는 지 알 필요 도 없고,저 장 된 데이터 가 더미 에서 얼마나 오래 살아 야 하 는 지 알 필요 도 없다 는 것 이다.그래서 더미 속 에 저장 소 를 분배 하 는 것 은 유연성 이 크다.대상 을 만 들 려 면 new 가 간단 한 코드 를 써 야 합 니 다.이 코드 를 실행 할 때 자동 으로 더미 에 저장 되 어 분 배 됩 니 다.물론 이런 유연성 을 위해 반드시 해당 하 는 대 가 를 치 러 야 한다.더미 로 저장 분 배 를 하 는 것 이 창고 로 저장 하 는 것 보다 더 많은 시간 이 필요 하 다.
4.정적 저장 소(static storage).이곳 의'정적'은'고정된 위치 에 있다'(RAM 에 있 음 에 도 불구 하고)를 말한다.정적 저장 소 에 프로그램 이 실 행 될 때 존재 하 는 데 이 터 를 저장 합 니 다.키워드 static 로 대상 의 특정 요 소 를 정적 으로 표시 할 수 있 지만 JAVA 대상 자 체 는 정적 저장 공간 에 저장 되 지 않 습 니 다.5.상수 저장 소(constant storage).상수 값 은 일반적으로 프로그램 코드 내부 에 직접 저장 되 는데,이렇게 하 는 것 은 영원히 변 하지 않 기 때문에 안전 하 다.때때로 삽입 식 시스템 에 서 는 상수 자체 가 다른 부분 과 분할 되 기 때문에 이 경우 ROM 에 넣 는 것 을 선택 할 수 있다.(이 점 의 예 는 문자열 상수 탱크 입 니 다.모든 문자 문자열 과 문자열 상수 표현 식 은 자동 으로 intered 되 어 특수 한 정적 저장 공간 에 놓 입 니 다.)6.비 RAM 저장 소.만약 데이터 가 프로그램 밖 에 완전히 존재 한다 면 프로그램의 어떠한 통제 도 받 지 않 고 프로그램 이 실행 되 지 않 았 을 때 도 존재 할 수 있다.
위의 이 단락 은《Thinking in Java》에서 발췌 한 것 이다.
-------------------------------------------------------------------------------------------------이 대상 들 은 new 를 통 해 만들어 집 니 다.프로그램 코드 로 표시 할 필요 가 없습니다.더 미 는 쓰레기 회수 로 책임 집 니 다.더 미 는 메모리 크기 를 동적 으로 분배 할 수 있 고 생존 기간 도 컴 파일 러 에 게 미리 알려 주지 않 아 도 됩 니 다.실행 할 때 동적 으로 메모 리 를 분배 하기 때문에 자바 의 쓰레기 수집 기 는 더 이상 사용 하지 않 는 데 이 터 를 자동 으로 받 습 니 다.그러나 실행 할 때 동적 으로 메모 리 를 분배 해 야 하기 때문에 액세스 속도 가 느 린 것 이 단점 이다.자바 의 대상 과 배열 은 모두 더미 에 저장 되 어 있 습 니 다.스 택 의 장점 은 액세스 속도 가 쌓 이 는 것 보다 빠 르 고 레지스터 에 버 금 가 며 스 택 데 이 터 를 공유 할 수 있다 는 것 이다.그러나 스 택 에 존재 하 는 데이터 크기 와 생존 기간 은 반드시 확정 되 고 유연성 이 부족 하 다 는 것 이 단점 이다.스 택 에는 기본 형식의 변수(int,short,long,byte,float,double,boolean,char)와 대상 참조 가 저장 되 어 있 습 니 다.
스 택 은 매우 중요 한 특수성 이 있 는데 바로 스 택 에 존재 하 는 데 이 터 를 공유 할 수 있다 는 것 이다.만약 우리 가 동시에 정의 한다 면:int a=3;int b = 3 ; 컴 파일 러 가 int a=3 을 먼저 처리 합 니 다.우선 스 택 에 a 라 는 변 수 를 만 든 다음 스 택 에 3 이라는 값 이 있 는 지 찾 습 니 다.찾 지 못 하면 3 을 저장 하고 a 를 3 으로 가 리 킵 니 다.이어서 int b=3 처리 하기;b 의 인용 변 수 를 만 든 후에 스 택 에 3 이라는 값 이 있 기 때문에 b 를 3 으로 직접 가리 킵 니 다.이렇게 해서 a 와 b 가 동시에 3 을 가리 키 는 상황 이 발생 했다.이때,다시 a=4;그러면 컴 파일 러 는 스 택 에 4 값 이 있 는 지 다시 검색 하고 없 으 면 4 를 저장 하고 a 를 4 로 가리 키 도록 합 니 다.만약 이미 있다 면,바로 a 를 이 주소 로 가리 키 세 요.따라서 a 값 의 변 화 는 b 의 값 에 영향 을 주지 않 습 니 다.이러한 데이터 의 공유 와 두 대상 의 인용 이 동시에 한 대상 을 가리 키 는 이러한 공 유 는 다르다 는 것 을 주의해 야 한다.이러한 상황 에서 a 의 수정 은 b 에 영향 을 주지 않 고 컴 파일 러 에 의 해 이 루어 지 며 공간 을 절약 하 는 데 유리 하기 때문이다.한 대상 의 인용 변 수 는 이 대상 의 내부 상 태 를 수정 하여 다른 대상 의 인용 변수 에 영향 을 줄 수 있 습 니 다.
이상 의 내용 도 인터넷 에서 발췌 한 것 이다.
 
의혹:'Thinking in java 4'에 서 는 이렇게 말 하지 않 았 습 니 다.책 에 서 는 기본 메타 데이터 에 대한 저장 은 stack 에서 변수 로 직접 저장 된다 고 합 니 다.이 점 에 대해 서 는 우선 상부 의 이 해 를 취 할 수 있 으 며,나중에 명확 해 질 필요 가 있다.
다음 에 제 가 몇 가지 예 를 들 겠 습 니 다.
public class TestStr { 
 public static void main(String[] args) { 
 //          1   。"  "           
 String str1 = "  " ; 
 String str2 = "  " ; 
 System.out.println(str1==str2);//true 
 
 //          2   ,        
 String str3 = new String("  " ); 
 String str4 = new String("  " ); 
 System.out.println(str3==str4);//false 
 
 //          1   。9         
 int i = 9; 
 int j = 9; 
 System.out.println(i==j);//true 
 
 //          1   。1          
 Integer l = 1;//   
 Integer k = 1;//    
 System.out.println(l==k);//true 
 
 //       ,         2   。  1          
 Integer l1 = new Integer(1); 
 Integer k1 = new Integer(1); 
 System.out.println(l1==k1);//false     17jquery 
 
 //          1   。i1,i2         ,  256          
 Integer i1 = 256; 
 Integer i2 = 256; 
 System.out.println(i1==i2);//false 
 } 
} 
상기 마지막 두 개의 Integer 대상 에 대한 예 에 대해 서 는 자동 으로 포장 할 때 값 이–128 에서 127 사이 의 값 에 대해 인 스 턴 스 를 사용 합 니 다.
다음은 문자열 상수 탱크()의 예 입 니 다.
String s1 = "aaa" + "bbb"; // 대상 이 하나 생 겼 다.
상수 의 값 이 컴 파일 할 때 확정 되 었 기 때문이다.여기 서"aa"와"bb"는 상수 이기 때문에 변수 s1 의 값 은 컴 파일 할 때 확인 할 수 있 습 니 다.이 줄 코드 를 컴 파일 한 후의 효 과 는 다음 과 같 습 니 다.
String s1 ="aaabbb";
그래서 여 기 는 대상'aaabbb'만 만 들 었 고 문자열 풀 에 저장 되 었 습 니 다.
다른:=="대상 을 판단 할 때 사실은 대상 이 창고 에 있 는 주소 에 따라 대상 이 같 는 지 아 닌 지 를 판단 하 는 것 이지 hashcode 값 에 따라 판단 하 는 것 이 아니다.
인터넷 에서 자바 String 의 HashCode 와 equal 에 대한 정 리 를 보 는 것 이 좋 습 니 다.기록 은 다음 과 같다.1.hashSet 에서 중복 여 부 를 비교 하 는 근 거 는 a.hasCode()=b.hasCode()&&a.equals(b)내용 은 17jquery 2.String 의 hashCode 근거:char[i]에 의존 하 는 int 값 으로 char[i]의 배열 순서 알고리즘 과 계산 한 것 이다(원본 코드 를 볼 수 있다).String 에 의존 하지 않 는 ref.3.String 의 equals 근거:a==b||(a.length=b.length&&{a[i]=b[i]})4.a==b 를 사용 할 때 만 비교 하 는 ref 입 니 다.즉,이때 야 말로 비교 가 a 와 b 가 같은 대상 인지 아 닌 지 5.결론:서로 다른 ref 의 String 은 집합 중의 같은 요소 로 여 겨 질 수 있 습 니 다.
---------------------------------------------------------------------
다음은 JAVA 의 더미,창고 와 상수 탱크 를 소개 합 니 다.
1.레지스터
가장 빠 른 저장 소 는 컴 파일 러 가 수요 에 따라 분 배 됩 니 다.우 리 는 프로그램 에서 제어 할 수 없습니다.
2.창고
기본 형식의 변수 데이터 와 대상 의 인용 을 저장 하지만 대상 자 체 는 스 택 에 저장 하지 않 고 쌓 기(new 에서 나 온 대상)나 상수 탱크 에 저장 합 니 다(문자열 상수 대상 은 상수 탱크 에 저장 합 니 다).
3.더미
new 에서 나 온 모든 대상 을 저장 합 니 다.
4.정적 영역
정적 구성원 저장(static 정의)
5.상수 탱크
문자열 상수 와 기본 형식 상수(Public static final)를 저장 합 니 다.
6.비 RAM 저장 소
하드디스크 등 영구 저장 공간
여기 서 우 리 는 주로 스 택,쌓 기와 상수 지 에 관심 을 가지 고 스 택 과 상수 지 의 대상 을 공유 할 수 있 으 며 쌓 인 대상 에 대해 공유 할 수 없습니다.스 택 의 데이터 크기 와 수명 주 기 는 확실 합 니 다.가리 키 는 데 이 터 를 참조 하지 않 으 면 이 데 이 터 는 사라 집 니 다.쌓 인 대상 은 쓰레기 수 거기 가 수 거 를 담당 하기 때문에 크기 와 생명주기 가 확실 하지 않 아 유연성 이 크다.
문자열:대상 의 인용 은 스 택 에 저 장 됩 니 다.컴 파일 기간 이 만 들 어 졌 다 면 상수 탱크 에 저 장 됩 니 다.실행 기간(new 에서 나 온)이 어야 확인 할 수 있 는 것 은 더미 에 저 장 됩 니 다.equals 와 같은 문자열 은 상수 탱크 에 영원히 한 부 만 있 고 쌓 여 있 습 니 다.
다음 코드 와 같이:
String s1 =  "china" ;  
String s2 =  "china" ;  
String s3 =  "china" ;  
String ss1 =  new  String ( "china" );  
String ss2 =  new  String ( "china" );  
String ss3 =  new  String ( "china" );  

기본 유형의 변수 와 상수:변수 와 인용 은 스 택 에 저장 되 고 상수 탱크 에 저 장 됩 니 다.
다음 코드 와 같이:
int  i1 =  9 ;  
int  i2 =  9 ;  
int  i3 =  9 ;  
public   static   final   int  INT1 =  9 ;  
public   static   final   int  INT2 =  9 ;  
public   static   final   int  INT3 =  9 ; 

구성원 변수 와 부분 변수:구성원 변 수 는 방법 외부,클래스 의 내부 정의 변수 입 니 다.부분 변 수 는 방법 이나 구문 블록 내부 에서 정의 하 는 변수 입 니 다.부분 변 수 는 초기 화 되 어야 합 니 다.형식 매개 변 수 는 부분 변수 이 고 부분 변수의 데 이 터 는 스 택 메모리 에 존재 합 니 다.스 택 메모리 의 부분 변 수 는 방법 이 사라 지면 서 사라 집 니 다.
구성원 변 수 는 쌓 인 대상 에 저장 되 어 있 으 며 쓰레기 회수 기 가 수 거 를 책임 집 니 다.
다음 코드 와 같이:
class  BirthDate {  
private   int  day;  
private   int  month;  
private   int  year;  
public  BirthDate ( int  d,  int  m,  int  y )  {  
	day = d;  
	month = m;  
	year = y;  
}  


get,set 방법 생략...} 
public   class  Test{  
	public   static   void  main ( String args[] ) {  

          int  date =  9 ;  

          Test test =  new  Test ();  

           test.change ( date );  

           BirthDate d1=  new  BirthDate ( 7 , 7 , 1970 );  

           }  

          public   void  change1 ( int  i ) { i =  1234 ;  

          } 

}

상기 코드 에 대해 date 는 부분 변수 이 고 i,d,m,y 는 모두 부분 변수 이 며 day,month,year 는 구성원 변수 입 니 다.다음은 코드 가 실 행 될 때의 변 화 를 분석 합 니 다.
1.main 방법 실행 시작:
              int  date =  9 ; 
date 부분 변수,기본 형식,참조 와 값 이 스 택 에 있 습 니 다.
2.test 를 대상 으로 인용 하여 스 택 에 존재 하고 대상(new Test()은 쌓 여 있 습 니 다.
              Test test =  new  Test ();  
3.
              test.change ( date );  
i 는 국부 변수 로 인용 과 값 이 창고 에 존재 합 니 다.방법 change 실행 이 완료 되면 i 는 스 택 에서 사라 집 니 다.
4.
              BirthDate d1=  new  BirthDate ( 7 , 7 , 1970 );  
d1 을 대상 으로 인용 하여 스 택 에 존재 합 니 다.대상(new BirthDate()은 더미 에 존재 합 니 다.그 중에서 d,m,y 는 부분 변수 로 스 택 에 저장 되 고 그들의 유형 은 기본 형식 이기 때문에 그들의 데이터 도 스 택 에 저 장 됩 니 다.day,month,year 는 구성원 변수 로 더미 에 저 장 됩 니 다(new BirthDate().BirthDate 구조 방법 이 실행 되면 d,m,y 는 스 택 에서 사라 집 니 다.
5.main 방법 이 실행 되면 date 변수,test,d1 참조 가 스 택 에서 사라 지고 new Test(),new BirthDate()는 쓰레기 수 거 를 기다 릴 것 입 니 다.
이상 의 내용 의 소 개 를 통 해 당신 에 게 도움 을 줄 수 있 기 를 바 랍 니 다.

좋은 웹페이지 즐겨찾기