나는 CMSClassUnloadingEnabled
“PermGen 문제를 제거한다”( btw 가 아닌 ) 와 같은 매우 희미한 고급 정의 외에 Java VM 플래그가 실제로 수행 하는 것에 대한 정의를 찾을 수 없다 .
Sun / Oracle 사이트를 살펴 보았고 옵션 목록 조차 실제로 실제로 무엇을 말하지는 않습니다.
플래그의 이름을 기준으로 CMS 가비지 콜렉터는 기본적으로 언로드 클래스를하지 않으며이 플래그를 설정하지만 확실하지 않습니다.
답변
업데이트이 답변은 Java 5-7과 관련이 있으며 Java 8에는 다음 사항이 수정되었습니다. https://blogs.oracle.com/poonam/about-g1-garbage-collector,-permanent-generation-and-metaspace Kudos는 mt 로 이동 하십시오 . 울루
Java 5-7의 경우 :
세계에서 표준 Oracle / Sun VM보기는 다음과 같습니다. 클래스는 영원합니다. 따라서 일단로드되면 더 이상 신경 쓰지 않아도 메모리에 남아 있습니다. 순전히 “설정”클래스가 많지 않기 때문에 일반적으로 문제가되지 않습니다. 따라서 1MB를 차지하더라도 누가 신경 써야합니다.
그러나 최근에는 런타임에 클래스를 정의하는 Groovy와 같은 언어가 있습니다. 스크립트를 실행할 때마다 하나 이상의 새 클래스가 만들어지고 PermGen에 영원히 머무 릅니다. 서버를 실행하는 경우 메모리 누수가 있음을 의미합니다.
CMSClassUnloadingEnabled
GC 를 활성화 하면 PermGen도 스윕하고 더 이상 사용되지 않는 클래스를 제거합니다.
[편집] 또한 활성화해야합니다 UseConcMarkSweepGC
( Sam Hasler 덕분에 ). 이 답변을 참조하십시오 : https://stackoverflow.com/a/3720052/2541
답변
블로그 게시물에 따르면 Java JVM의 가장 완벽한 -XX 옵션 목록은 CMS 가비지 수집기에서 클래스 언로드가 활성화되어 있는지 확인합니다. 기본값은 false
입니다. 라는 또 다른 옵션이 ClassUnloading
있습니다 true
(아마도) 다른 쓰레기 수집에 영향을 미치는 기본적으로는.
아이디어는 GC가 이전에로드 된 클래스가 더 이상 JVM의 어느 곳에서도 사용되지 않음을 감지하면 클래스 바이트 코드 및 / 또는 기본 코드를 보유하는 데 사용 된 메모리를 회수 할 수 있다는 것입니다.
CMSClassUnloadingEnabled를 설정 하면 현재 CMS 수집기를 사용중인 경우 permgen 문제에 도움이 될 수 있습니다 . 그러나 CMS를 사용하지 않거나 클래스 로더 관련 메모리 누수가 발생할 가능성이 있습니다. 후자의 경우 클래스는 GC에 사용되지 않은 것처럼 보이지 않으므로 언로드되지 않습니다.
Aaron Digulla는 “수업은 영원합니다”라고 말합니다. 순수한 Java 세계에서도 마찬가지입니다. 실제로 클래스의 수명은 클래스 로더와 연결되어 있습니다. 따라서 클래스 로더가 가비지 수집되도록 정렬 할 수 있다면 (그리고 항상 쉬운 것은 아닙니다)로드 된 클래스도 가비지 수집됩니다.
실제로, 이것은 웹 애플리케이션을 재 전개 할 때 발생합니다. (또는 최소한 permgen 스토리지 누출로 이어지는 문제점을 피할 수있는 경우에 발생합니다.)
답변
이것이 유용한 예 :
-XX:+CMSPermGenSweepingEnabled -XX:+CMSClassUnloadingEnabled
Weblogic 10.3 JVM을 설정 하면 JAX-WS 구현이 모든 웹 서비스 호출에 대해 새 프록시 클래스를 작성하여 메모리 부족 오류가 발생하는 문제를 해결하는 데 도움이되었습니다.
추적하기가 쉽지 않았습니다. 다음 코드는 항상 동일한 프록시 클래스를 반환했습니다.port
final MyPortType port =
Service.create(
getClass().getResource("/path/to.wsdl"),
new QName("http://www.example.com", "MyService"))
.getPort(
new QName("http://www.example.com", "MyPortType"),
MyPortType.class);
내부적으로이 프록시는의 인스턴스에 위임되었습니다.이 인스턴스는 매번 호출 할 때마다 증가 weblogic.wsee.jaxws.spi.ClientInstance
된 새 $Proxy[nnnn]
클래스에 위임되었습니다 n
. 플래그를 추가 할 때 n
여전히 증가했지만 최소한 임시 클래스는 메모리에서 제거되었습니다.
보다 일반적으로, 이것은 자바 리플렉션 및 프록시를 많이 사용하는 경우 매우 유용 할 수 있습니다. java.lang.reflect.Proxy