Java에서 클래스를 언로드하시겠습니까?
커스텀 클래스 로더가 있기 때문에 데스크톱 애플리케이션이 대화해야 하는 AppServer에서 동적으로 클래스 로드를 시작할 수 있습니다.이렇게 하는 데 필요한 항아리의 양이 너무 많아서 (배송을 원했다면) 이렇게 했습니다.또한 AppServer 라이브러리에서 런타임에 동적으로 클래스를 로드하지 않으면 버전 문제가 발생합니다.
두 개의 다른 AppServer와 대화해야 하는 문제에 부딪혔는데, 어떤 클래스를 먼저 로드하느냐에 따라서는 문제가 발생할 수 있습니다.실제로 JVM을 죽이지 않고 클래스의 언로딩을 강제할 수 있는 방법이 있습니까?
이게 말이 됐으면 좋겠어
클래스를 언로드할 수 있는 유일한 방법은 사용되는 Classloader가 가비지 수집일 경우입니다.즉, 모든 클래스 및 클래스 로더에 대한 참조 자체가 도도새의 길을 가야 합니다.
문제에 대한 하나의 가능한 해결책은 모든 jar 파일에 대한 Classloader와 특정 jar classloader에 실제 클래스 로드를 위임하는 각 AppServer에 대한 Classloader를 갖는 것입니다.이렇게 하면 각 앱 서버에 대해 서로 다른 버전의 jar 파일을 가리킬 수 있습니다.
하지만 이것은 사소한 것이 아니다.OSGi 플랫폼에서는 각 번들의 클래스로더가 다르고 플랫폼에 의해 종속성이 해결되기 때문에 이 작업만 수행하려고 합니다.한 번 살펴보는 게 좋을 것 같아요.
OSGI 를 사용하지 않는 경우는, JAR 파일 마다 1 개의 JarClassloader 클래스의 인스턴스를 사용할 수 있습니다.
또한 Classloader를 확장하는 새로운 MultiClassloader 클래스를 만듭니다.이 클래스는 내부적으로 JarClassloaders의 배열(또는 목록)을 가집니다.defineClass() 메서드는 정의를 찾을 수 있거나 NoClassDefFoundException이 느려질 때까지 모든 내부 클래스로더를 반복합니다.클래스에 새로운 JarClassloader를 추가하기 위해 몇 가지 접근기 메서드를 제공할 수 있습니다.MultiClassLoader에는 몇 가지 구현이 가능하기 때문에 직접 작성할 필요도 없습니다.
서버에 접속할 때마다 MultiClassloader를 설치하는 경우 원칙적으로 각 서버가 다른 버전의 동일한 클래스를 사용할 수 있습니다.
프로젝트에서 MultiClassloader 아이디어를 사용한 적이 있습니다.이 프로젝트에서는 사용자 정의 스크립트를 포함하는 클래스를 메모리에서 로드 및 언로드해야 했습니다.그것은 매우 잘 동작했습니다.
예, 클래스를 로드하고 나중에 "언로드"하는 방법이 있습니다.이 방법은 고급 클래스 로더(시스템 클래스 로더)와 앱 서버의 클래스 로더 사이에 있는 자체 클래스 로더를 구현하고 앱 서버의 클래스 로더가 클래스 로더를 상위 로더에 위임하도록 하는 것입니다.
클래스는 패키지, 이름 및 처음 로드한 클래스 로더에 의해 정의됩니다.JVM을 시작할 때 가장 먼저 로드되는 "프록시" 클래스 로더를 프로그래밍합니다.워크플로우:
- 프로그램이 시작되고 실제 "main" 클래스가 이 프록시 클래스 로더에 의해 로드됩니다.
- 정상적으로 로드되는 모든 클래스는 (즉, 계층을 파괴할 수 있는 다른 클래스 로더 구현을 통하지 않음) 이 클래스 로더에 위임됩니다.
- 는 「」를 위임합니다.
java.x
★★★★★★★★★★★★★★★★★」sun.x
시스템 클래스로더(시스템클래스로더 이외의 클래스로더를 통해 로드하지 마십시오). - 교환 가능한 모든 클래스에 대해 클래스 로더를 인스턴스화하여(클래스를 실제로 로드하고 부모 클래스로더에 위임하지 않음) 이를 통해 로드합니다.
- 클래스 패키지/이름을 키로 저장하고 클래스로더를 값으로 데이터 구조(해시맵)에 저장합니다.
- 프록시 클래스 로더는 이전에 로드된 클래스에 대한 요청을 받을 때마다 이전에 저장된 클래스 로더의 클래스를 반환합니다.
- 클래스 로더에 의해 클래스의 바이트 배열을 찾고(또는 데이터 구조에서 키/값 쌍을 "삭제"하고), 변경할 경우 클래스를 새로고침하는 것으로 충분합니다.
바로 실행 시 ClassCastException 또는 LinkError 등이 발생하지 않습니다.
클래스 로더 계층에 대한 자세한 내용은 (네, 바로 여기서 구현하고 있습니다;-) Ted Neward의 "Server-Based Java Programming"을 참조하십시오.이 책은 당신이 원하는 것과 매우 유사한 것을 구현하는데 도움이 되었습니다.
커스텀 클래스 로더를 작성했습니다.클래스 로더를 GC하지 않고 개별 클래스를 언로드할 수 있습니다.Jar 클래스 로더
클래스 로더는 까다로운 문제가 될 수 있습니다.여러 개의 클래스로더를 사용하고 있으며 그 상호작용이 명확하고 엄격하게 정의되어 있지 않으면 특히 문제가 발생할 수 있습니다.실제로 클래스를 언로드하려면 언로드하려는 클래스(및 해당 인스턴스)에 대한 참조를 모두 삭제해야 합니다.
이런 종류의 일을 해야 하는 대부분의 사람들은 결국 OSGi를 사용하게 됩니다.OSGi는 매우 강력하고 놀라울 정도로 가볍고 사용하기 쉽습니다.
ClassLoader는 언로드할 수 있지만 특정 클래스는 언로드할 수 없습니다.구체적으로는 사용자가 제어할 수 없는 ClassLoader에서 생성된 클래스를 언로드할 수 없습니다.
가능하다면 당신이 언로드할 수 있도록 당신의 ClassLoader를 사용하는 것이 좋습니다.
클래스에는 ClassLoader 인스턴스에 대한 암묵적인 강한 참조가 있으며, 그 반대도 마찬가지입니다.Java 객체와 마찬가지로 가비지가 수집됩니다.도구 인터페이스 등을 누르지 않으면 개별 클래스를 제거할 수 없습니다.
여전히 메모리 누수가 발생할 수 있습니다.클래스 또는 클래스 로더에 대한 강한 참조는 모든 것을 누설합니다.이는 ThreadLocal, java.sql의 Sun 구현에서 발생합니다.예를 들어 DriverManager 및 java.beans입니다.
라이브에서 언로드 클래스가 JConsole에서 동작하는지 여부를 보고 있는 경우,java.lang.System.gc()
수업 마지막에 논리를 뺄 때 말이야가비지 컬렉터를 명시적으로 트리거합니다.
언급URL : https://stackoverflow.com/questions/148681/unloading-classes-in-java
'programing' 카테고리의 다른 글
C 문자열에서 공백 제거 (0) | 2022.08.14 |
---|---|
C의 정적 아사트 (0) | 2022.08.14 |
Laravel Spark v4.0.9에서 "Vue 패키지 버전 불일치" 오류를 수정하려면 어떻게 해야 합니까? (0) | 2022.08.13 |
Enum 값을 문자열 리터럴로 사용 (0) | 2022.08.13 |
해시맵의 get/put 복잡성 (0) | 2022.08.13 |