Java 클래스를 내리는 방법
나는 이 질문에게 몇 시간을 받았다. 최근에 Xyling는 그의 블로그에 있는 동일한 질문을 질문했다. 따라서 나는 간단한 설명이 순서에 있을지도 모른다 생각했다.
종류를 내리기 위하여는 당신은 주문 classloader를 창조하고 그것을 사용하여 종류를 적재해야 한다. 수고양이는 그것을 하고 그래서 JRun를 한다. 당신은 보기를 위해 수고양이 부호를 볼 수 있다.
당신이 종류로 행해진 후에 당신은 가변을 재할당하거나 영으로 하기 위하여 놓아서 종류 장전기에 뿐만 아니라 종류에 모든 참고를 풀어 놓을 필요가 있다.
더 이상 바이트가 해방될 수 있을 때까지 다음 종류를 내리는 System.gc를 위한 기대 () 또는 당신은 반복에서 그것을 직접 부른다. 아무리 일반적으로 그것을 불러서 두번 목적을 달성한다.
주: 당신은 단 하나 종류를 내릴 수 없다. 당신은 그것과 함께 classloader를 내려야 한다. 이렇게 명백하게 체계 classloader는 이 업무를 위해 적당하가 아니다.
주 2: 이것은 JSP 페이지가 당신에 변화 부호 역동적으로 언제나 다시 탄약이 재지는 방법 이다. 그리고 그렇습니다 그리하여 처음은 연속적인 시간을 그 때 적재하기 위하여 매우 오래 걸린다.
어떻게의 밑에 에, 자바 소프트웨어 신청하는, 기술 |
|
RSS 2.0 |
이 기사를 이메일을 보내십시오
당신은 또한 읽고 싶을지도 모른다 |


Technorati 마음에 드는 것에게 추가하십시오

































2005년 3월 15일 6:31 pm에
안녕,
이 정보를 대단히 감사합니다.
나가 나의 질문 자체를 여기에서 확장하는 경우에는 꺼리는가? 실제로, 나는 URLClassLoader를 통해 나의 종류를 적재한다. 그리고 일반적으로 나는 URLClassLoader를 통해 선적 단지 파일이다. 지금 나는 이 단지 파일을 내려지는 원한다. 나는 단지 파일을 위한 URLClassLoader까지 당신의 논리를 역시 확장해서 좋은가?
2005년 3월 15일 6:33 pm에
당신을 감사하십시오.
2005년 3월 15일 6:41 pm에
실제로, JSP 첫번째 짐 시간은 이다 훨씬 더 느리면 자바를 한 경우에 다시 탄약이 재지는 종류 뿐만 아니라 때문이, (bytecode에서 종류를 적재하는 것은 그것을 오래 걸리지 않는다; -). bytecode를 JSP 근원에 변화가 자바 근원으로 첫째로 개조되어야 하는 때, 그 후에 안으로 생성하는 더 뜻깊은 소요 시간은 ClassLoader에 의해 그 때 적재될 수 있는 바이트 부호 소요되고. 따라서, 추가하십시오 2개를 분석하거나 생성한다 1개 바이트 짐에 주기를…
2005년 3월 16일 4:28 pm에
당신이 종류의 동적인 다시 탄약을 재기에 재미있는 강선전도를 보기에 흥미있는 경우에, http://www.platonos.org에 우리의 플러그 접속식 엔진에 있는 근원을 체크아웃하십시오. 우리는 뿐만 아니라 플러그 접속식을, 그들의 자신의 classloader에 각각 적재한다, 그러나 우리는 지금 역동적으로 또 다른 한개 에 의지하고 있는 플러그 접속식의 부분을 내리는 기능을 추가하고 있다.
플러그 접속식 B는 실시를을 제공한다 플러그 접속식 A가 공용영역을 제공할 때 결국, 플러그 접속식 B ClassLoader는 (A의 classloader에 대표단을 통해서) 실시 종류에 자물쇠 자체를 붙든다. 우리는 후에도 플러그 접속식 A에 있는 classloader를 밖으로 영으로 한다 (B의 실시 종류가 자물쇠를 위에 지킨다 우리가 아)를 내리는 것을 시도하는 경우에, B의 classloader는 공용영역 종류 때문에 A에 자물쇠를 지킨다. 기본적으로 당신은 이것이 있다:
공용영역 pluginAInterface {}
종류 pluginBImpl는 pluginAInterface를 실행한다 {}
각각은 다른 classloader에 의해 적재된다. 이용될 때, 플러그 접속식 B의 classloader는 그 pluginBImpl 방안 pluginAInterface를 본다. 그것은 그것을 찾는 플러그 접속식 B의 classloader에서 시작한다. 그것은 (pluginAInterface 종류가 플러그 접속식 A의 classloader classpath에 있기 때문에) 그것을 거기 찾아낼 수 없다. 플러그 접속식 엔진은 플러그 접속식 A의 classloader에 검사를 이 pluginAInterface 종류를 위한 바이트 부호를 찾아내는 파견한다. 그것은 거기, 그래서 플러그 접속식 A의 classloader "짐" bytecode 찾아냈다, 그러나 플러그 접속식 B의 classloader는 bytecode를 "그것을 찾아내는 A에 처음에 파견해서 본다". 한 번 찾아내는, 시렁 상점에서 건설되는 classloader classloader: 종류 포인터 (의미, classloader 및 종류는 기억에 있는 실제적인 bytecode에 포인터로 일종 "열쇠"를 구성한다) 그래서 더 이상 A. 그러나, 큰 문제, 1 차적으로 그들의 종류 참고에 파견하는 필요 pluginBImpl 종류가 그것을 실행하는 공용영역의 명부를 소유하기 위한 것이다 유지한다 이다. 이것에 관하여 나쁜 것은 런타임에 영으로 하기 위하여 거기 없다 이것을 놓는 아무 방법도 이다!
따라서 우리의 간계는 classloader를 소유하기 위한 것이어 플러그 접속식 내의 두번째 classloader를 그것이 있기 위하여 플러그 접속식 또 다른 한개에 의해 실행된 각 공용영역을 허용하기 위하여 이용하기 위한 것이어 그래서 우리는 그 것을 버려서 좋 얻기 위하여 일하기 위하여 다시 탄약을 재거나 내린.
그것은 까다롭다, 그러나 목적을 달성한다. 아마 아직도 숨겨지은 문제점 우리는 아직 우연히 만나지 않았다.
2005년 3월 제 18 3:00 AM에
그렇습니다 @Goldy Lukka. 당신은 능력 있어야에 한다. 나가 URLClassLoader, 그래서 나를 이런 식으로 사용하지 않았다 그러나 무엇이든을 참고를 단단하 에 제거해 달라고 하는 경우에 확실하지 않다. 나는 스파이크 해결책이 순서에 다는 것을 짐작한다
BTW: 나는 당신의 위치를 즐긴다.
아주 유익한 코멘트를 위한 @Kevin 감사.
2005년 3월 제 19 2:54 AM에
Goldy Lukka,
.jar 파일에 다시 탄약을 재거나 내리기 위하여 URLClassLoader 이용에 간계는 .jar 파일 내의 종류의 무엇이든이 다른 부호에 의하여 참조 사항를 붙이고 있지 않다는 것을 확인하고 있다. 속국은 처리하기 어렵다. 우리는 서로에 의존하여 플러그 접속식의 문제점으로 중대한 고통에 결심하는 것을 시도하기 위하여 내리거나 다시 탄약을 잰다 갔다. 우리는 아직도 문제를 그것을 만드는 일어나 많은 경우에 달라고 한다. 어떤 경우에, 플러그 접속식의 개발자는 다만 제대로 다른 플러그 접속식 종류에 가지고 있는 어떤 참고든지 청소한다 그런 방법으로 그들의 플러그 접속식 되도록 동을 만들고 싶은 경우에, 진짜로 그것을 개발해야 한ㄴ다는 것을 알고 있 한다.
당신의 .jar 파일이 밝히기 위하여 다만 실시를 추가하는 경우에, 중핵 신청은 API 의 당신을 쉽게 그것을 제거할 수 있어야 한다 조화시킨다. 우리가 발견했다시피, implemting 종류는 실행하는 공용영역에 참고 (자물쇠)를 지킨다. 따라서 당신의 .jar 파일에 있는 종류는에 ref를 좋은 공용영역, 당신 단순히 밖으로 영으로 하고 그것을 그리고/또는 영으로 한다 .jar를 적재한 classloader를 지킬 것입니다 당신은 잘 이다. 그러나 .jar 파일이 다른 종류가 (어쩌면 다른 .jar 파일의) 사용하는 공용영역을 제공하는 경우에, 그것은 더 어렵게 된다. 적재한 .jar 안에서 아무 종류나 사용하는 .jar 파일을 적재한 classloader의 이상으로 아무 종류나 또한 내려져야 한다. 또 다시, 우리의 엔진을 나타나서, 그것은 처리하기 어려울 수 있는 사건을 내리기의 연쇄 반응을 시작한다. 우리는 플러그 접속식 당 2개의 classloader 경우가 있어서 문제를 해결했다. 다른 플러그 접속식 종류에 의해 실행되는 공용영역을 취급하는 1개, 그리고 종류의 나머지를 위해 하나. 그것은 예쁘지 않다, 그러나 여태까지는 작동한다. 우리는 아직도 이것에게 더 나은 과정을 하기 위하여 실험하고 있다.
2005년 3월 22일 7:35 pm에
Kevin,
이것이 가능했던 경우에 당신이 공용영역 종류 (Class#getInterfaces () 영으로 할)에 참고를 수 없다 진실하다, 당신이 런타임에 바이트 부호에 있는 공용영역을 제거한ㄴ다는 것을, 에서 의미할 것입니다:
공중 종류 MyTestImpl는 TestImpl를 실행한다
{
}
에
공중 종류 MyTestImpl
{
}
동일은 superclasses를 위해 진실하다.
2005년 3월 23 6:23 pm에
플러그 접속식이 일인 방법 훌륭한 정보이다. 나는 주문 종류 장전기의 가장 간단한 가능한 부호가 있어서 좋다. 궁극적으로 주문 종류 장전기는 과태 classloader 가 또는 적재된 아닙니다 nees 인가? 만약에 이렇게 그 때 i가 프로그램의 그런 종류의 callgraph에 있는 classloader에 볼 수 있으면?
2005년 4월 1일 6:02 AM에
@Sandip URLClassLoader를 사용하지 않기 위하여 왜? 또한 자바 자습서에서 제공된 견본 ClassLoader 부호가 있다.
2006년 9월 11일 11:39 AM에
정보를 위한 감사합니다.
나는 나가 있는 어떤 사람들을 위해 여기에서 중요한 생각하는 인터넷에 무언가를 읽는다:
2개의 종류는 동일한 포장의 ClassLoader 다른 목표에 의해 적재되는 경우에 이지 않는다!
당신은 2개의 종류를 가진 포장이 다는 것을 생각한, 사람은 공중과 포장 개인 다른 사람이다. 이들은 ClassLoader (또는 아강) 동일한 목표에 의해 적재되어야 한다. 공중 종류가 포장 개인적인 종류에 접근할 것을 시도할 때 당신이 당신 실행 시간 오류를 얻지 않는 경우에는.
따라서 당신이 각 종류를 위한 ClassLoader 새로운 목표를 만드는 것을 계획한 경우에, 각 포장을 위해 ClassLoader 1개의 목표를 사용하는 것을 고려하십시오. 다른 선택권은 모든 종류에게 공중을 하기 위한 것이다.