programing tip

Java에서 메모리를 비우는 방법?

itbloger 2020. 6. 25. 21:25
반응형

Java에서 메모리를 비우는 방법?


C의 free()기능 과 유사하게 Java에서 메모리를 비울 수있는 방법이 있습니까? 아니면 객체를 null로 설정하고 GC에만 의존하는 옵션입니까?


Java는 관리 메모리를 사용하므로 메모리를 할당 할 수있는 유일한 방법은 new연산자 를 사용하는 것 뿐이며 메모리 할당을 해제 할 수있는 유일한 방법은 가비지 수집기를 사용하는 것입니다.

메모리 관리 백서 (PDF)는 진행 상황을 설명하는 데 도움이 될 수 있습니다.

System.gc()가비지 수집기가 즉시 실행되도록 제안하기 위해 전화 걸 수도 있습니다 . 그러나 Java 런타임은 코드가 아닌 최종 결정을 내립니다.

에 따르면 Java 문서 ,

gc 메소드를 호출하면 Java Virtual Machine이 현재 사용중인 메모리를 빠르게 재사용 할 수 있도록하기 위해 사용하지 않는 객체를 재활용하는 데 노력할 것을 제안합니다. 메소드 호출에서 제어가 리턴되면, JVM (Java Virtual Machine)은 삭제 된 모든 오브젝트에서 공간을 확보하기 위해 최선을 다했습니다.


아무도 객체 참조를 명시 적으로 설정하는 것에 대해 언급 한 적이없는 것 같습니다 null. 이는 여러분이 고려하고 싶은 메모리를 "비우는"합법적 인 기술입니다.

예를 들어, List<String>크기가 매우 커지는 메소드의 시작 부분에 a를 선언 했지만 메소드 중간 쯤까지만 필요하다고 가정하십시오. 이 시점에서 목록 참조를 설정하여 null메소드가 완료되기 전에 가비지 수집기가이 객체를 잠재적으로 회수 할 수있게합니다 (그리고 참조는 범위를 벗어남).

실제로이 기술은 거의 사용하지 않지만 매우 큰 데이터 구조를 처리 할 때는 고려할 가치가 있습니다.


System.gc(); 

가비지 수집기를 실행합니다.

gc 메소드를 호출하면 Java Virtual Machine이 현재 사용중인 메모리를 빠르게 재사용 할 수 있도록하기 위해 사용하지 않는 객체를 재활용하는 데 노력할 것을 제안 합니다. 메소드 호출에서 제어가 리턴되면, JVM (Java Virtual Machine)은 삭제 된 모든 오브젝트에서 공간을 확보하기 위해 최선을 다했습니다.

권장하지 않습니다.

편집 : 2009 년에 원래의 답변을 썼습니다. 지금은 2015 년입니다.

가비지 수집기는 Java가 사용 된 ~ 20 년 동안 꾸준히 향상되었습니다. 이 시점에서 가비지 수집기를 수동으로 호출하는 경우 다른 방법을 고려할 수 있습니다.

  • 제한된 수의 머신에서 GC를 강제 실행하는 경우 현재 머신에서 로드 밸런서 포인트를 멀리두고 연결된 클라이언트에 대한 서비스가 완료 될 때까지 기다렸다가 연결을 끊기 위해 일정 시간이 지난 후 제한 시간이 초과 될 수 있습니다. -JVM을 다시 시작하십시오. 이것은 끔찍한 해결책이지만 System.gc ()를보고있는 경우 강제 저장 공간이 가능한 스톱 갭이 될 수 있습니다.
  • 다른 가비지 수집기를 사용하십시오. 예를 들어, (최근 6 년에 새로 도입 된) G1 수집기는 일시 중지가 적은 모델입니다. 전반적으로 더 많은 CPU를 사용하지만 실행을 강제로 멈추지 않는 것이 가장 좋습니다. 서버 CPU에는 거의 모든 코어가 여러 개 있기 때문에 이것이 실제로 사용할 수있는 절충점입니다.
  • 메모리 사용 튜닝 플래그를보십시오. 특히 최신 버전의 Java에서 장기 실행 객체가 많지 않은 경우 힙에서 newgen의 크기를 늘리십시오. newgen (young)은 새로운 객체가 할당되는 곳입니다. 웹 서버의 경우 요청을 위해 생성 된 모든 것이 여기에 배치 되며이 공간이 너무 작 으면 Java는 객체를 수명이 더 긴 메모리로 업그레이드하는 데 시간이 더 오래 걸리므로 죽이는 데 비용이 많이 듭니다. (newgen이 너무 작 으면 비용을 지불하게됩니다.) 예를 들어 G1에서 :
    • XX : G1NewSizePercent (기본값은 5, 아마도 중요하지 않습니다.)
    • XX : G1MaxNewSizePercent (기본값은 60입니다. 아마도이 값을 올리십시오.)
  • 더 이상 일시 정지해도 가비지 수집기에 문제가 없다고 알려주십시오. 이로 인해 시스템이 나머지 제약 조건을 유지할 수 있도록 GC가 더 자주 실행됩니다. G1에서 :
    • XX : MaxGCPauseMillis (기본값 : 200)

* "나는 개인적으로 미래의 적절한 삭제를 위해 자리 표시 자로 nulling 변수를 사용합니다. 예를 들어, 실제로 배열 자체를 삭제 (null 만들기)하기 전에 배열의 모든 요소를 ​​무효화하는 데 시간이 걸립니다."

이것은 불필요합니다. Java GC가 작동하는 방식은 객체를 참조하지 않는 객체를 찾는 것입니다. 따라서 참조가있는 Object x (= variable) a가 있으면 GC가 삭제하지 않습니다. 그 객체에 :

a -> x

이보다 null이 null 인 경우 :

a -> null
     x

이제 x는 참조를 가리 키지 않고 삭제됩니다. a가 x와 다른 객체를 참조하도록 설정했을 때도 마찬가지입니다.

따라서 객체 x, y 및 z를 참조하는 배열 arr과 배열을 참조하는 변수 a가 있으면 다음과 같습니다.

a -> arr -> x
         -> y
         -> z

이보다 null이 null 인 경우 :

a -> null
     arr -> x
         -> y
         -> z

So the GC finds arr as having no reference set to it and deletes it, which gives you this structure:

a -> null
     x
     y
     z

Now the GC finds x, y and z and deletes them aswell. Nulling each reference in the array won't make anything better, it will just use up CPU time and space in the code (that said, it won't hurt further than that. The GC will still be able to perform the way it should).


A valid reason for wanting to free memory from any programm (java or not ) is to make more memory available to other programms on operating system level. If my java application is using 250MB I may want to force it down to 1MB and make the 249MB available to other apps.


To extend upon the answer and comment by Yiannis Xanthopoulos and Hot Licks (sorry, I cannot comment yet!), you can set VM options like this example:

-XX:+UseG1GC -XX:MinHeapFreeRatio=15 -XX:MaxHeapFreeRatio=30

In my jdk 7 this will then release unused VM memory if more than 30% of the heap becomes free after GC when the VM is idle. You will probably need to tune these parameters.

While I didn't see it emphasized in the link below, note that some garbage collectors may not obey these parameters and by default java may pick one of these for you, should you happen to have more than one core (hence the UseG1GC argument above).

VM arguments

Update: For java 1.8.0_73 I have seen the JVM occasionally release small amounts with the default settings. Appears to only do it if ~70% of the heap is unused though.. don't know if it would be more aggressive releasing if the OS was low on physical memory.


I have done experimentation on this.

It's true that System.gc(); only suggests to run the Garbage Collector.

But calling System.gc(); after setting all references to null, will improve performance and memory occupation.


If you really want to allocate and free a block of memory you can do this with direct ByteBuffers. There is even a non-portable way to free the memory.

However, as has been suggested, just because you have to free memory in C, doesn't mean it a good idea to have to do this.

If you feel you really have a good use case for free(), please include it in the question so we can see what you are rtying to do, it is quite likely there is a better way.


Entirely from javacoffeebreak.com/faq/faq0012.html

A low priority thread takes care of garbage collection automatically for the user. During idle time, the thread may be called upon, and it can begin to free memory previously allocated to an object in Java. But don't worry - it won't delete your objects on you!

When there are no references to an object, it becomes fair game for the garbage collector. Rather than calling some routine (like free in C++), you simply assign all references to the object to null, or assign a new class to the reference.

Example :

public static void main(String args[])
{
  // Instantiate a large memory using class
  MyLargeMemoryUsingClass myClass = new MyLargeMemoryUsingClass(8192);

  // Do some work
  for ( .............. )
  {
      // Do some processing on myClass
  }

  // Clear reference to myClass
  myClass = null;

  // Continue processing, safe in the knowledge
  // that the garbage collector will reclaim myClass
}

If your code is about to request a large amount of memory, you may want to request the garbage collector begin reclaiming space, rather than allowing it to do so as a low-priority thread. To do this, add the following to your code

System.gc();

The garbage collector will attempt to reclaim free space, and your application can continue executing, with as much memory reclaimed as possible (memory fragmentation issues may apply on certain platforms).


In my case, since my Java code is meant to be ported to other languages in the near future (Mainly C++), I at least want to pay lip service to freeing memory properly so it helps the porting process later on.

I personally rely on nulling variables as a placeholder for future proper deletion. For example, I take the time to nullify all elements of an array before actually deleting (making null) the array itself.

But my case is very particular, and I know I'm taking performance hits when doing this.


* "For example, say you'd declared a List at the beginning of a method which grew in size to be very large, but was only required until half-way through the method. You could at this point set the List reference to null to allow the garbage collector to potentially reclaim this object before the method completes (and the reference falls out of scope anyway)." *

This is correct, but this solution may not be generalizable. While setting a List object reference to null -will- make memory available for garbage collection, this is only true for a List object of primitive types. If the List object instead contains reference types, setting the List object = null will not dereference -any- of the reference types contained -in- the list. In this case, setting the List object = null will orphan the contained reference types whose objects will not be available for garbage collection unless the garbage collection algorithm is smart enough to determine that the objects have been orphaned.


Althrough java provides automatic garbage collection sometimes you will want to know how large the object is and how much of it is left .Free memory using programatically import java.lang; and Runtime r=Runtime.getRuntime(); to obtain values of memory using mem1=r.freeMemory(); to free memory call the r.gc(); method and the call freeMemory()


Recommendation from JAVA is to assign to null

From https://docs.oracle.com/cd/E19159-01/819-3681/abebi/index.html

Explicitly assigning a null value to variables that are no longer needed helps the garbage collector to identify the parts of memory that can be safely reclaimed. Although Java provides memory management, it does not prevent memory leaks or using excessive amounts of memory.

An application may induce memory leaks by not releasing object references. Doing so prevents the Java garbage collector from reclaiming those objects, and results in increasing amounts of memory being used. Explicitly nullifying references to variables after their use allows the garbage collector to reclaim memory.

One way to detect memory leaks is to employ profiling tools and take memory snapshots after each transaction. A leak-free application in steady state will show a steady active heap memory after garbage collections.

참고URL : https://stackoverflow.com/questions/1567979/how-to-free-memory-in-java

반응형