CodeGym /Java Blog /무작위의 /개체 수명 주기
John Squirrels
레벨 41
San Francisco

개체 수명 주기

무작위의 그룹에 게시되었습니다
안녕! 컴퓨터의 메모리 용량이 제한되어 있다고 말해도 놀라지 않을 것 같습니다. :)
개체 수명 주기 - 1
하드 드라이브(RAM 크기의 몇 배)도 좋아하는 게임, TV 프로그램 및 기타 항목으로 가득 차게 할 수 있습니다. 이를 방지하려면 컴퓨터 메모리의 현재 상태를 모니터링하고 불필요한 파일을 삭제해야 합니다. 이 모든 것이 Java 프로그래밍과 어떤 관련이 있습니까? 아주 직접적으로! 결국, 객체를 생성하면 Java 시스템이 해당 객체에 메모리를 할당하게 됩니다 . 대규모 실제 프로그램은 수만 또는 수십만 개의 개체를 생성하고 각 개체에 대해 메모리 청크가 할당됩니다. 그러나 이러한 개체가 얼마나 많이 존재한다고 생각하십니까? 프로그램이 실행되는 동안 모두 "살아" 있습니까? 당연히 아니지. 모든 이점에도 불구하고 Java 객체는 불멸이 아닙니다. :) 객체에는 자체 수명 주기가 있습니다. 오늘 우리는 코드 작성에서 약간의 휴식을 취하고 이 프로세스를 탐색할 것입니다 :) 프로그램 작동 방식을 이해하고 리소스를 관리하는 데에도 매우 중요합니다. 그렇다면 물체의 생명은 어디에서 시작됩니까? 인간처럼 태어날 때부터, 즉 창조될 때부터.

Cat cat = new Cat();// Our Cat object's lifecycle begins now!
먼저 JVM(Java Virtual Machine)이 객체 생성에 필요한 메모리를 할당합니다. cat그런 다음 추적할 수 있도록 참조(우리의 경우 )를 만듭니다 . 그런 다음 모든 변수가 초기화되고 생성자가 호출되며 새로운 개체가 이제 자체 수명을 유지합니다 :) 개체 수명은 다양합니다. 여기에는 정확한 수치가 없습니다. 어쨌든 개체는 프로그램에 상주하며 일정 기간 동안 해당 기능을 수행합니다. 정확히 말하면 개체에 대한 참조가 있는 한 개체는 "활성"입니다. 참조가 없는 즉시 객체는 "죽습니다". 예를 들어:

public class Car {
  
   String model;

   public Car(String model) {
       this.model = model;
   }

   public static void main(String[] args) {
       Car lamborghini  = new Car("Lamborghini Diablo");
       lamborghini = null;

   }

}
메서드 에서 main()"Lamborghini Diablo" Car 개체는 두 번째 줄에서 활성 상태를 멈춥니다. 그것에 대한 참조는 하나만 있었고 참조는 null로 설정되었습니다. 디아블로에 대한 언급이 남아 있지 않기 때문에 "쓰레기"가 됩니다. 이를 위해 참조를 0으로 설정할 필요는 없습니다.

public class Car {

   String model;

   public Car(String model) {
       this.model = model;
   }

   public static void main(String[] args) {
       Car lamborghini  = new Car("Lamborghini Diablo");

       Car lamborghiniGallardo = new Car("Lamborghini Gallardo");
       lamborghini = lamborghiniGallardo;
   }

}
여기서 우리는 두 번째 개체를 생성하고 이를 Lamborghini 참조에 할당했습니다. 이제 두 개의 참조가 Lamborghini Gallardo개체를 가리키지만 Lamborghini Diablo개체에는 아무 것도 없습니다. 이것은 Diablo객체가 쓰레기가 된다는 것을 의미합니다. 이때 Java의 내장 가비지 수집기 (GC)가 시작됩니다.
개체 수명 주기 - 2
가비지 수집기는 메모리 해제, 즉 메모리에서 불필요한 개체 제거를 담당하는 내부 Java 메커니즘입니다. 로봇청소기로 표현하기로 선택한 이유가 있습니다. 가비지 수집기는 거의 같은 방식으로 작동합니다. 백그라운드에서 프로그램을 "이동"하여 가비지를 수집합니다. 실제로 상호 작용할 필요가 없습니다. 그것의 임무는 프로그램에서 더 이상 사용되지 않는 개체를 삭제하는 것입니다. 따라서 다른 개체에 대한 메모리를 해제합니다. 강의 시작 부분에서 실생활에서 컴퓨터 상태를 모니터링하고 오래된 파일을 삭제해야 한다고 말했던 것을 기억하십니까? Java 개체에 대해 이야기하는 경우 가비지 수집기가 자동으로 이 작업을 수행합니다.. 가비지 수집기는 프로그램이 실행될 때 여러 번 시작됩니다. 명시적으로 호출하거나 명령을 내릴 필요가 없습니다(기술적으로는 가능함). 나중에 가비지 수집기에 대해 더 자세히 이야기하고 작동 방식을 더 자세히 분석하겠습니다. 가비지 컬렉터가 객체에 도달하면 객체가 소멸되기 직전에 객체의 특수 finalize()메서드가 호출됩니다. 이 메서드는 개체에서 사용하는 특정 추가 리소스를 해제하기 위해 호출할 수 있습니다. 메서드 finalize()는 Object 클래스에 속합니다. 즉, equals(), hashCode()toString()(이전에 만난 적이 있음)와 비슷합니다. 모든 객체는 그것을 가지고 있습니다 . 다른 방법과 다른 점은...이걸 어떻게 말해야 할까요...매우 의지가 강하다는 점입니다. 그것으로 우리는 그것을 의미합니다개체가 소멸되기 전에 항상 호출되는 것은 아닙니다 . 프로그래밍은 매우 정확한 활동입니다. 프로그래머는 컴퓨터에게 무언가를 하라고 지시하고 컴퓨터는 그 일을 합니다. 나는 당신이 이런 종류의 행동에 익숙해졌다고 가정하므로 처음에는 다음과 같은 생각을 받아들이기가 어려울 수 있습니다: "객체가 파괴되기 전에 Object 클래스의 메서드가 호출됩니다 finalize(). " 그래도 이게 현실입니다. Java 시스템 자체가 경우에 따라 finalize()를 호출할지 여부를 결정합니다. 실험으로 다음 코드를 실행해 보겠습니다.

public class Cat {

   private String name;

   public Cat(String name) {
       this.name = name;
   }

   public Cat() {
   }

   public static void main(String[] args) throws Throwable {

       for (int i = 0 ; i < 1000000; i++) {

           Cat cat = new Cat();
           cat = null;// The first object becomes available for garbage collection here
       }
   }

   @Override
   protected void finalize() throws Throwable {
       System.out.println("The Cat is destroyed!");
   }
}
객체 를 만들고 Cat다음 줄에서 객체에 대한 유일한 참조를 0으로 만듭니다. 그리고 우리는 그것을 백만 번 합니다. 메서드 를 명시적으로 재정의했습니다 finalize(). 개체가 소멸될 때마다 Cat총 100만 번 문자열을 표시해야 합니다. 하지만! 정확히 말하자면, 내 컴퓨터에서는 37346 번만 실행되었습니다! 즉, 내 Java 머신은 finalize()27건 중 1건에서만 메서드를 호출하기로 결정했습니다. 다른 경우에는 가비지 수집에 이 호출이 포함되지 않았습니다. 이 코드를 직접 실행해 보세요. 아마 다른 결과를 얻게 될 것입니다. 보시다시피 finalize()신뢰할 수 있는 파트너를 부르기가 어렵습니다 :) 그래서 미래를 위한 작은 팁이 있습니다. finalize()중요한 리소스를 해제하는 방법에 의존하지 마십시오.JVM이 호출할 수도 있고 호출하지 않을 수도 있습니다. 누가 알아? 개체가 살아있는 동안 일부 성능에 중요한 리소스(예: 열린 데이터베이스 연결)를 보유한 경우 개체가 더 이상 필요하지 않을 때 리소스를 해제하는 특수 메서드를 만들고 명시적으로 호출하는 것이 좋습니다. 그렇게 하면 프로그램 성능이 저하되지 않는다는 것을 확실히 알 수 있습니다. 우리는 메모리와 가비지 수집 작업이 매우 중요한 주제이며 실제로 그렇다는 말로 시작했습니다. 리소스를 잘못 처리하고 불필요한 개체를 정리하는 방법을 잘못 이해하면 가장 불쾌한 버그 중 하나인 메모리 누수 가 발생할 수 있습니다 . 이것은 가장 잘 알려진 프로그래밍 오류 중 하나입니다. 자체 Wikipedia 기사 도 있습니다.. 잘못 작성된 코드는 새로 생성된 개체에 대해 매번 메모리가 할당되지만 오래되고 불필요한 개체는 가비지 수집에 사용할 수 없는 상황을 만들 수 있습니다. 우리는 이미 로봇 진공 청소기 비유를 만들었으므로 로봇을 실행하기 전에 집안 곳곳에 양말을 뿌리고 유리 꽃병을 부수고 바닥 전체에 레고 조각을 남겨두면 어떤 일이 일어날지 상상해 보십시오. 당연히 로봇은 무언가를 하려고 하지만 언젠가는 붙잡을 것입니다.
개체 수명 주기 - 3
진공 청소기가 제대로 작동하려면 바닥을 적절한 모양으로 유지하고 처리할 수 없는 모든 것을 들어 올려야 합니다. 가비지 수집기는 동일한 원칙을 따릅니다. 프로그램에 정리할 수 없는 많은 개체(예: 로봇 진공 청소기용 양말 또는 레고)가 있으면 언젠가는 메모리가 부족해집니다. 프로그램이 중단될 뿐만 아니라 컴퓨터에서 실행 중인 다른 모든 프로그램도 중단됩니다. 결국, 그들도 충분한 기억력을 갖지 못할 것입니다(비유로 돌아가면, 바닥의 깨진 유리는 진공청소기뿐만 아니라 집에 사는 사람들도 멈춥니다). 요컨대 이것이 Java에서 개체 수명 주기 및 가비지 수집의 모습입니다. 이것을 외울 필요는 없습니다. 작동 방식을 이해하는 것만으로도 충분합니다. 다음 수업에서 우리는 ' 이러한 프로세스에 대해 더 자세히 설명하겠습니다. 하지만 지금은 CodeGym 작업 해결로 돌아갈 수 있습니다 :) 행운을 빕니다!
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION