Java에서 가비지 수집을 강제하는 방법은 무엇입니까?
까다로운 경우에도 Java에서 가비지 수집을 강제 할 수 있습니까? 내가 알고 System.gc();
하고 Runtime.gc();
있지만, 그들은 단지 GC를 수행하는 것이 좋습니다. GC를 어떻게 강제 할 수 있습니까?
가장 좋은 방법은 System.gc()
가비지 수집기에서 수집하려는 힌트를 간단히 호출 하는 것입니다. 가비지 수집기는 비 결정적이므로 강제 로 즉시 수집 할 수있는 방법이 없습니다 .
jlibs 라이브러리는 가비지 컬렉션에 대한 좋은 유틸리티 클래스가 있습니다 . WeakReference 객체 로 멋진 작은 트릭을 사용하여 가비지 수집을 강제 할 수 있습니다 .
/**
* This method guarantees that garbage collection is
* done unlike <code>{@link System#gc()}</code>
*/
public static void gc() {
Object obj = new Object();
WeakReference ref = new WeakReference<Object>(obj);
obj = null;
while(ref.get() != null) {
System.gc();
}
}
GC를 강제하는 가장 좋은 방법은 사용자 지정 JVM을 작성하는 것입니다. 가비지 콜렉터는 플러그 가능하므로 사용 가능한 구현 중 하나를 선택하여 조정할 수 있다고 생각합니다.
참고 : 이것은 쉬운 대답이 아닙니다.
은 Using 자바 (Java ™) 가상 공작 기계 인터페이스 (JVM TI)를 함수
jvmtiError ForceGarbageCollection(jvmtiEnv* env)
"VM이 가비지 수집을 수행하도록합니다." JVM TI는 Java 플랫폼 디버거 아키텍처 (JPDA)의 일부 입니다.
예 , 거의 같은 순서로 메소드를 호출해야하며 동시에이 메소드는 다음과 같습니다.
System.gc ();
System.runFinalization ();
이 두 메소드의 사용을 동시에 청소하는 하나의 오브젝트 인 경우에도 가비지 콜렉터 finalise()
는 도달 할 수없는 오브젝트 의 메소드 를 사용하여 지정된 메모리를 해제하고 finalize()
메소드 상태를 수행합니다.
그러나 가비지 수집기를 사용하면 메모리보다 최악의 소프트웨어에 과부하가 발생할 수 있기 때문에 가비지 수집기를 사용하는 것이 끔찍한 관행이지만 가비지 수집기는 자체 스레드를 가지고 있기 때문에 제어 할 수 없습니다. gc가 사용하는 알고리즘은 더 많은 시간이 걸리고 매우 비효율적 인 것으로 간주됩니다. gc의 도움으로 소프트웨어가 최악인지 확인해야합니다. 확실히 파산했기 때문에 좋은 해결책은 gc에 의존해서는 안됩니다.
참고 : 이것은 finalize 메소드에서 객체를 재할 당하지 않는 경우에만 작동합니다.이 경우 객체가 살아 있으면 기술적으로 가능한 부활을 갖게됩니다.
OutOfMemoryError에 대한 문서에 따르면 VM이 전체 가비지 수집 후 메모리를 회수하지 않으면 발생하지 않는다고 선언합니다. 따라서 오류가 발생할 때까지 메모리 할당을 계속하면 이미 전체 가비지 수집을 수행했을 것입니다.
아마 당신이 정말로 묻고 싶은 질문은 "가비지 수집으로 회수해야한다고 생각되는 기억을 어떻게 되 찾을 수 있을까?"였습니다.
System.gc ()가 아닌 GC를 수동으로 요청하려면 다음을 수행하십시오.
- 이동 : JDK의 bin 폴더 (예 : C : \ Program Files \ Java \ jdk1.6.0_31 \ bin)
- jconsole.exe를 엽니 다
- 원하는 로컬 프로세스에 연결하십시오.
- 메모리 탭으로 이동하여 GC 수행을 클릭하십시오.
.gc는 향후 릴리스에서 제거 할 후보입니다. Sun 엔지니어는 한 번은 전 세계에서 20 명 미만이 실제로 .gc ()를 사용하는 방법을 알고 있다고 언급했습니다. SecureRandom이 생성 한 데이터를 사용하는 데이터 구조, 약 4 만 개가 넘는 개체에서 vm은 포인터가 부족한 것처럼 속도가 느려집니다. 분명히 그것은 16 비트 포인터 테이블을 질식 시켰으며 고전적인 "실패한 기계"동작을 보여 주었다.
나는 -Xms 등을 시도하여 약 57, xxx 개의 무언가가 나올 때까지 비트를 돌리고 있었다. 그런 다음 gc () 이후에 57,127에서 57,128 사이의 gc를 실행합니다-캠프 Easy Money의 코드 부풀림 속도에 대해.
설계에는 근본적인 재 작업, 아마도 슬라이딩 윈도우 접근 방식이 필요합니다.
명령 행에서 GC를 트리거 할 수 있습니다. 배치 / 크론 탭에 유용합니다.
jdk1.7.0/bin/jcmd <pid> GC.run
보다 :
JVM 사양은 가비지 수집과 관련하여 아무 것도 말하지 않습니다. 이로 인해 공급 업체는 GC를 자유롭게 구현할 수 있습니다.
따라서이 모호함은 가비지 콜렉션 동작에 불확실성을 유발합니다. 가비지 수집 방법 / 알고리즘에 대해 알고 싶다면 JVM 세부 정보를 확인해야합니다. 또한 동작을 사용자 정의하는 옵션도 있습니다.
가비지 수집을 강제해야하는 경우 리소스 관리 방법을 고려해야합니다. 메모리에 지속되는 큰 객체를 생성하고 있습니까? Disposable
인터페이스가 있고 dispose()
완료되었을 때 호출하지 않는 큰 객체 (예 : 그래픽 클래스)를 작성 하고 있습니까? 클래스 수준에서 단일 메서드 내에서만 필요한 것을 선언하고 있습니까?
가비지 수집이 필요한 이유를 설명하면 더 좋습니다. SWT를 사용하는 경우 메모리 Image
와 같은 자원을 제거 하고 Font
메모리 를 비울 수 있습니다 . 예를 들어 :
Image img = new Image(Display.getDefault(), 16, 16);
img.dispose();
처리되지 않은 리소스를 결정하는 도구도 있습니다.
메모리가 부족하고 점점 더 많은 것을 얻는 OutOfMemoryException
다면 java -Xms128m -Xmx512m
그냥 대신 프로그램을 시작하여 java가 사용할 수있는 힙 공간을 늘려보십시오 java
. 이렇게하면 초기 힙 크기는 128Mb이고 최대 512Mb이며 표준 32Mb / 128Mb보다 훨씬 큽니다.
다른 옵션은 새 객체를 만들지 않는 것입니다.
Java에서 GC의 필요성을 줄이기 위해 객체 풀링 이 사라졌습니다.
오브젝트 풀링은 일반적으로 오브젝트 작성 (가벼운 오브젝트의 경우)보다 빠르지 않지만 가비지 콜렉션보다 빠릅니다. 10,000 개의 객체를 만들고 각 객체가 16 바이트 인 경우 GC가 회수해야하는 160,000 바이트입니다. 반면에 10,000 개가 동시에 필요하지 않은 경우 풀을 생성하여 객체를 재활용 / 재사용하여 새 객체를 만들 필요가없고 기존 객체를 GC 할 필요가 없습니다.
이와 같은 것 (평가되지 않음). 스레드 안전을 원할 경우 ConcurrentLinkedQueue에 대한 LinkedList를 교체 할 수 있습니다.
public abstract class Pool<T> {
private int mApproximateSize;
private LinkedList<T> mPool = new LinkedList<>();
public Pool(int approximateSize) {
mApproximateSize = approximateSize;
}
public T attain() {
T item = mPool.poll();
if (item == null) {
item = newInstance();
}
return item;
}
public void release(T item) {
int approxSize = mPool.size(); // not guaranteed accurate
if (approxSize < mApproximateSize) {
recycle(item);
mPool.add(item);
} else if (approxSize > mApproximateSize) {
decommission(mPool.poll());
}
}
public abstract T newInstance();
public abstract void recycle(T item);
public void decommission(T item) { }
}
On OracleJDK 10 with G1 GC, a single call to System.gc()
will cause GC to clean up the Old Collection. I am not sure if GC runs immediately. However, GC will not clean up the Young Collection even if System.gc()
is called many times in a loop. To get GC to clean up the Young Collection, you must allocate in a loop (e.g. new byte[1024]
) without calling System.gc()
. Calling System.gc()
for some reason prevents GC from cleaning up the Young Collection.
Really, I don't get you. But to be clear about "Infinite Object Creation" I meant that there is some piece of code at my big system do creation of objects whom handles and alive in memory, I could not get this piece of code actually, just gesture!!
This is correct, only gesture. You have pretty much the standard answers already given by several posters. Let's take this one by one:
- I could not get this piece of code actually
Correct, there is no actual jvm - such is only a specification, a bunch of computer science describing a desired behaviour ... I recently dug into initializing Java objects from native code. To get what you want, the only way is to do what is called aggressive nulling. The mistakes if done wrong are so bad doing that we have to limit ourselves to the original scope of the question:
- some piece of code at my big system do creation of objects
Most of the posters here will assume you are saying you are working to an interface, if such we would have to see if you are being handed the entire object or one item at a time.
If you no longer need an object, you can assign null to the object but if you get it wrong there is a null pointer exception generated. I bet you can achieve better work if you use NIO
Any time you or I or anyone else gets: "Please I need that horribly." it is almost universal precursor to near total destruction of what you are trying to work on .... write us a small sample code, sanitizing from it any actual code used and show us your question.
Do not get frustrated. Often what this resolves to is your dba is using a package bought somewhere and the original design is not tweaked for massive data structures.
That is very common.
You can try using Runtime.getRuntime().gc()
or use utility method System.gc()
Note: These methods do not ensure GC. And their scope should be limited to JVM rather than programmatically handling it in your application.
FYI
The method call System.runFinalizersOnExit(true) guarantees that finalizer methods are called before Java shuts down. However, this method is inherently unsafe and has been deprecated. An alternative is to add “shutdown hooks” with the method Runtime.addShutdownHook.
Masarrat Siddiqui
There is some indirect way for forcing garbage collector. You just need to fill heap with temporary objects until the point when garbage collector will execute. I've made class which forces garbage collector in this way:
class GarbageCollectorManager {
private static boolean collectionWasForced;
private static int refCounter = 0;
public GarbageCollectorManager() {
refCounter++;
}
@Override
protected void finalize() {
try {
collectionWasForced = true;
refCounter--;
super.finalize();
} catch (Throwable ex) {
Logger.getLogger(GarbageCollectorManager.class.getName()).log(Level.SEVERE, null, ex);
}
}
public int forceGarbageCollection() {
final int TEMPORARY_ARRAY_SIZE_FOR_GC = 200_000;
int iterationsUntilCollected = 0;
collectionWasForced = false;
if (refCounter < 2)
new GarbageCollectorManager();
while (!collectionWasForced) {
iterationsUntilCollected++;
int[] arr = new int[TEMPORARY_ARRAY_SIZE_FOR_GC];
arr = null;
}
return iterationsUntilCollected;
}
}
Usage:
GarbageCollectorManager manager = new GarbageCollectorManager();
int iterationsUntilGcExecuted = manager.forceGarbageCollection();
I don't know how much this method is useful, because it fills heap constantly, but if you have mission critical application which MUST force GC - when this may be the Java portable way to force GC.
I would like to add some thing here. Please not that Java runs on Virtual Machine and not actual Machine. The virtual machine has its own way of communication with the machine. It may varry from system to system. Now When we call the GC we ask the Virtual Machine of Java to call the Garbage Collector.
Since the Garbage Collector is with Virtual Machine , we can not force it to do a cleanup there and then. Rather that we queue our request with the Garbage Collector. It depends on the Virtual Machine, after particular time (this may change from system to system, generally when the threshold memory allocated to the JVM is full) the actual machine will free up the space. :D
The following code is taken from the assertGC(...) method. It tries to force the nondeterministic garbage collector to collect.
List<byte[]> alloc = new ArrayList<byte[]>();
int size = 100000;
for (int i = 0; i < 50; i++) {
if (ref.get() == null) {
// Test succeeded! Week referenced object has been cleared by gc.
return;
}
try {
System.gc();
} catch (OutOfMemoryError error) {
// OK
}
try {
System.runFinalization();
} catch (OutOfMemoryError error) {
// OK
}
// Approach the jvm maximal allocatable memory threshold
try {
// Allocates memory.
alloc.add(new byte[size]);
// The amount of allocated memory is increased for the next iteration.
size = (int)(((double)size) * 1.3);
} catch (OutOfMemoryError error) {
// The amount of allocated memory is decreased for the next iteration.
size = size / 2;
}
try {
if (i % 3 == 0) Thread.sleep(321);
} catch (InterruptedException t) {
// ignore
}
}
// Test failed!
// Free resources required for testing
alloc = null;
// Try to find out who holds the reference.
String str = null;
try {
str = findRefsFromRoot(ref.get(), rootsHint);
} catch (Exception e) {
throw new AssertionFailedErrorException(e);
} catch (OutOfMemoryError err) {
// OK
}
fail(text + ":\n" + str);
Source (I added some comments for clarity): NbTestCase Example
If you are using JUnit and Spring, try adding this in every test class:
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
참고URL : https://stackoverflow.com/questions/1481178/how-to-force-garbage-collection-in-java
'Programming' 카테고리의 다른 글
버전 12에서 업그레이드 한 후 IntelliJ 13 IDEA가 왜 그렇게 느립니까? (0) | 2020.05.05 |
---|---|
파이썬에서 "i + = x"는 "i = i + x"와 언제 다릅니 까? (0) | 2020.05.05 |
XML에서 '이미지에 contentDescription 속성 누락' (0) | 2020.05.05 |
Visual Studio 2019에서 Perfwatson2.exe를 비활성화하는 방법 (0) | 2020.05.05 |
IE11을 감지하는 방법? (0) | 2020.05.05 |