programing

System.gc()를 호출하는 것이 잘못된 방법인 이유는 무엇입니까?

itsource 2022. 8. 8. 16:14
반응형

System.gc()를 호출하는 것이 잘못된 방법인 이유는 무엇입니까?

자바에서 오브젝트를 강제로 해제하는 방법에 대한 질문에 답한 (남자는 1.5를 클리어하고 있었다)GB HashMap)를 사용하는 경우System.gc()전화하는 것은 나쁜 관행이라고 들었습니다.System.gc()수작업은 했지만, 코멘트가 완전히 설득력이 있는 것은 아니었다.게다가 아무도 감히 내 대답을 지지하거나 지지하지 않는 것 같았다.

거기서 나쁜 관행이라고 들었습니다만, 가비지 컬렉터의 실행이 체계적으로 세계를 정지시키는 것은 아니고, JVM에 의해서도 힌트로서만 유효하게 이용될 수 있기 때문에, 조금 당황하고 있습니다.

JVM이 메모리를 회수할 필요가 있는 경우는, 통상, 고객보다 JVM이 더 잘 알고 있습니다.또한 몇 킬로바이트의 데이터에 대해 걱정하는 것은 어리석은 일이라는 것도 알고 있습니다.또한 메가바이트의 데이터도 몇 년 전과는 다르다는 것도 알고 있습니다.그래도 1.5기가바이트?메모리에는 1.5GB의 데이터가 있습니다.어두운 곳이라고는 할 수 없습니다.System.gc()시스템적으로 나쁜가, 아니면 어느 시점에서 괜찮아지는가?

그래서 질문은 두 가지입니다.

  • 전화하는 것이 나쁜 방법인지 아닌지는System.gc()특정 구현에서 JVM에 대한 힌트에 불과합니까?아니면 항상 완전한 수집 사이클입니까?세상을 멈추지 않고 작업을 수행할 수 있는 가비지 컬렉터 구현이 실제로 있습니까? 답변에 대한 사람들의 다양한 주장을 조명해 주세요.
  • 문턱이 어디지?전화하는 것은 결코 좋은 생각이 아닐까요?System.gc()혹은, 그것이 받아들여질 때가 있는가?그렇다면 그 시간은 몇 시입니까?

모두가 피하라고 하는 이유는System.gc()근본적으로 망가진 코드를 보여주는 좋은 지표라는 거죠정확성을 위해 이 코드에 의존하는 모든 코드는 확실히 파손되어 있습니다.퍼포먼스를 위해 이 코드에 의존하는 모든 코드는 파손되어 있을 가능성이 높습니다.

당신은 당신이 어떤 종류의 쓰레기 수집기를 가지고 있는지 모릅니다.확실히 당신의 주장대로 「세상을 정지」하지 않는 사람도 있습니다만, 그렇게 똑똑하지 않은 JVM이나 여러가지 이유(아마도 전화에 접속하고 있을 가능성이 있습니다)로 인해, 그렇게 하지 않는 JVM도 있습니다.어떻게 될지 모르잖아

또한, 그것은 아무 것도 보장하지 않습니다.JVM은 사용자의 요청을 완전히 무시할 수 있습니다.

'무엇이 될지 모른다' '어쨌든 불러서는 안 된다'는 조합이 사람들이 '일반적으로 불러서는 안 된다'고 말하는 이유다.'사용해야 하는지 물어봐야 한다면 사용하지 말아야 한다'는 경우라고 생각합니다.


다른 스레드의 몇 가지 문제에 대처하기 위해 편집:

당신이 링크한 스레드를 읽고 나서, 제가 지적하고 싶은 것이 몇 가지 더 있습니다.먼저, 어떤 분이 전화를 걸라고 제안되었다.gc()메모리가 시스템에 반환될 수 있습니다.Java 힙 자체는 Java 할당과는 무관하게 확장됩니다.

와 같이 JVM은 메모리(수십 메가바이트)를 보유하고 필요에 따라 힙을 확장합니다.Java 오브젝트를 해방해도 반드시 그 메모리를 시스템으로 되돌리는 것은 아닙니다.앞으로 Java 할당을 위해 할당된 메모리를 자유롭게 유지할 수 있습니다.

할 수 있다는 것을 보여주기 위해서System.gc()아무것도 하지 않습니다.JDK 버그 6668279, 특히 VM 옵션이 있는 것을 확인합니다.

디폴트 콜:System.gc()유효하게 되어 있다(-XX:-DisableExplicitGC) 를 사용합니다.-XX:+DisableExplicitGC에의 콜을 무효로 하다System.gc()JVM은 필요에 따라 가비지 수집을 계속 수행합니다.

이미 설명했듯이 전화는system.gc() 가비지 콜렉터의 실행을 「유효하게 하는」코드가 파손되는 일이 있습니다.

그러나 전화하는 것이 나쁜 관행이라는 실용적인 이유는System.gc()비효율적이라는 것입니다.그리고 최악의 경우, 그것은 끔찍하게 비효율적이다!제가 설명해 드릴게요.

일반적인 GC 알고리즘에서는 힙 내의 불필요한 오브젝트가 아닌 오브젝트를 모두 통과하여 가비지를 식별하며 방문되지 않은 오브젝트는 가비지가 되어야 한다고 추론합니다.이를 통해 가비지 컬렉션의 총 작업을 실제 데이터 양에 비례하는 부분과 가비지 양에 비례하는 다른 부분으로 구성할 수 있습니다. 즉, 가비지 컬렉션의 총 작업을 모델링할 수 있습니다. work = (live * W1 + garbage * W2).

이제 단일 스레드 응용 프로그램에서 다음을 수행한다고 가정합니다.

System.gc(); System.gc();

첫 번째 콜은 (예측)로 할 수 있습니다.(live * W1 + garbage * W2)미해결 쓰레기를 처리하도록 하겠습니다.

두 번째 통화로 충분합니다.(live* W1 + 0 * W2)일을 하고 아무것도 되찾지 않는다.다른 말로 하자면(live * W1)아무것도 이루지 못했다.

수집기의 효율성을 쓰레기 단위 수집에 필요한 작업량으로 모델링할 수 있습니다. efficiency = (live * W1 + garbage * W2) / garbage따라서 GC를 최대한 효율적으로 만들기 위해 우리는 GC의 가치를 극대화할 필요가 있다.garbage즉, 힙이 가득 찰 때까지 기다립니다.(그리고 힙을 가능한 한 크게 만듭니다.)하지만 그건 다른 주제입니다.)

응용 프로그램이 (콜을 통해) 간섭하지 않는 경우System.gc()). GC는 히프가 가득 찰 때까지 기다렸다가 실행함으로써 가비지를 효율적으로1 수집할 수 있습니다.그러나 애플리케이션이 강제로 GC를 실행하면 힙이 가득 차지 않고 결과적으로 가비지가 비효율적으로 수집될 수 있습니다.또한 어플리케이션이 GC를 강제할수록 GC의 효율이 떨어집니다.

주의: 위의 설명은 일반적인 최신 GC가 힙을 "스페이스"로 분할하고, GC가 힙을 동적으로 확장할 수 있으며, 애플리케이션의 비배지 개체 작업 세트가 다를 수 있다는 사실을 얼버무립니다.그럼에도 불구하고, 동일한 기본 원칙이 모든 진정한 가비지2 수집가에게 적용됩니다.GC를 강제로 실행하는 것은 비효율적입니다.


1 - "스루풋" 수집기는 이렇게 동작합니다.CMS 및 G1과 같은 동시 수집기는 다른 기준을 사용하여 가비지 수집기를 시작할 시기를 결정합니다.

2 - 참조 카운트를 단독으로 사용하는 메모리 매니저도 제외합니다만, 현재 Java의 실장에서는 이 어프로치를 사용하고 있지 않습니다.좋은 이유로.

많은 사람들이 당신에게 이것을 하지 말라고 말하는 것 같다.동의하지 않습니다.레벨 로드와 같은 대규모 로드 프로세스 후에 다음과 같이 생각할 수 있습니다.

  1. 도달할 수 없고 gc'ed되지 않은 객체가 많습니다.
  2. 이 시점에서 사용자가 약간의 속도 저하를 견딜 수 있다고 생각하십니까?

System.gc()를 호출해도 문제가 없습니다.c/c++라고 생각합니다.inline키워드를 지정합니다.이는 개발자인 귀하께서 시간/성능이 보통만큼 중요하지 않으며 메모리 재확보용으로 사용될 수 있다고 판단하셨다는 것을 보여주는 힌트입니다.

아무것도 하지 말라는 충고는 옳다.효과가 있을 거라고 기대하지 마세요. 하지만 지금이 수집할 수 있는 시기라는 암시를 주는 것은 완벽하게 좋습니다.사용자가 프로그램(게임 레벨 중 등)과 적극적으로 대화하는 것보다 코드 내에서 중요하지 않은 시점(화면 로딩)에서 시간을 낭비하고 싶습니다.

수집을 강제하는 경우가 있습니다.특정 오브젝트 누수(네이티브코드 또는 크고 복잡한 콜백 상호작용)를 검출하려고 할 때.그리고 Matlab을 보는 것 같은 UI 컴포넌트도 있습니다.)이것은, 실가동 코드에 사용하지 말아 주세요.

사람들은 왜 사용하지 말아야 하는지를 잘 설명해 주었기 때문에 사용해야 할 몇 가지 상황을 말씀드리겠습니다.

(다음 코멘트는 CMS 컬렉터를 탑재한 Linux 상에서 실행되고 있는Hotspot에 적용됩니다.여기서 저는 다음과 같이 자신 있게 되었습니다.System.gc()실제로는 항상 완전한 가비지 컬렉션을 호출합니다).

  1. 애플리케이션을 기동한 후, 메모리의 사용 상황이 나빠질 가능성이 있습니다.테넌트 세대의 절반이 가비지로 가득 찰 수 있습니다.즉, 첫 번째 CMS에 훨씬 더 가깝습니다.그것이 중요한 어플리케이션에서는 System.gc()를 호출하여 라이브 데이터의 시작 상태로 힙을 "리셋"하는 것도 나쁘지 않습니다.

  2. #1과 마찬가지로 히프 사용량을 주의 깊게 감시하는 경우 기준 메모리 사용량을 정확하게 판독해야 합니다.애플리케이션 가동 시간의 처음 2분이 모두 초기화일 경우 강제로 실행하지 않으면 데이터가 엉망이 됩니다(아헴...).전면의 풀 gc.

  3. 실행 중에는 테넌트 세대에게 아무것도 승격하지 않도록 설계된 응용 프로그램이 있을 수 있습니다.그러나 테넌트 세대로 자동으로 이동하기 위해 그리 많지 않은 일부 데이터를 미리 초기화해야 할 수도 있습니다.모든 것이 셋업된 후 System.gc()를 호출하지 않는 한 데이터는 승격될 때까지 새로운 세대에 저장될 수 있습니다.즉, 통상적인 운용 시에 이러한 오브젝트를 프로모트 하는 것에 대해서, GC가 낮은 초고중저 레이텐시 애플리케이션이 큰 레이텐시 패널티(물론 비교적 높은 레이텐시 패널티)를 받게 됩니다.

  4. 메모리 누전 여부를 확인하기 위해 실제 가동 어플리케이션에서 System.gc 콜을 사용할 수 있도록 하는 것이 도움이 될 수 있습니다.시각 X 의 라이브 데이터 세트가 시각 Y 의 라이브 데이터 세트에 대해서 일정한 비율로 존재할 필요가 있는 것을 알고 있는 경우는, System.gc() 를 시각 X 와 시각 Y 로 호출해 메모리 사용량을 비교하는 것이 편리합니다.

이것은 매우 귀찮은 질문입니다.그리고 자바가 얼마나 유용한 언어이긴 하지만 많은 사람들이 자바에 반대하는데 기여하고 있다고 생각합니다.

"System.gc"를 신뢰할 수 없다는 사실은 매우 부담스럽고 언어에 "두려움, 불확실성, 의심"이라는 느낌을 쉽게 불러일으킬 수 있습니다.

대부분의 경우 중요한 이벤트가 발생하기 전에 사용자가 의도적으로 일으킨 메모리 급증에 대처하는 것이 좋습니다.이 때문에 사용자는 프로그램이 잘못 설계되었거나 응답하지 않는다고 생각할 수 있습니다.

쓰레기 수집을 통제하는 능력을 갖는 것은 매우 훌륭한 교육 도구가 될 것이고, 결과적으로 쓰레기 수집이 어떻게 작동하는지 그리고 프로그램이 통제된 행동뿐만 아니라 기본 행동을 이용하도록 하는 방법에 대한 사람들의 이해를 향상시킬 것이다.

이 스레드의 논거를 검토하겠습니다.

  1. 비효율적:

대부분의 경우 프로그램이 아무 것도 하지 않고 설계 방식 때문에 아무 것도 하지 않는다는 것을 알 수 있습니다.예를 들어 큰 대기 메시지박스를 사용하여 장시간 대기하고 있을 수 있습니다.또, 마지막에 가비지를 수집하기 위한 콜을 추가할 수도 있습니다.이는 가비지 수집에 걸리는 시간이 긴 대기 시간의 극히 일부에 불과하지만, 보다 중요한 조작 중에 gc가 동작하지 않기 때문입니다.

  1. 이는 항상 잘못된 관행이며 코드가 고장났음을 나타냅니다.

내 생각은 달라, 네가 어떤 쓰레기 수집기를 가지고 있는지는 중요하지 않아.그것의 역할은 쓰레기를 추적하고 청소하는 것이다.

사용량이 덜 중요한 시간에 gc를 호출하면 실행 중인 특정 코드에 의존하지만 대신 가비지 수집이 결정될 때 gc가 실행될 확률을 줄일 수 있습니다.

물론 원하는 대로 동작하지 않을 수도 있고 예상대로 동작하지 않을 수도 있지만, 호출할 경우 아무 일도 일어나지 않으며 사용자는 느림/다운타임을 기꺼이 견딜 수 있습니다.System.gc가 작동한다면 좋습니다!만약 그렇지 않다면, 적어도 넌 노력했어.가비지 콜렉터가 수동으로 기동하면 어떻게 행동해야 하는지에 대해 끔찍하게 예기치 않은 부작용을 일으키지 않는 한 단점은 없습니다.이것 자체가 불신을 일으킵니다.

  1. 일반적인 사용 사례는 아닙니다.

이것은 신뢰성 있게 달성할 수 없는 사용 사례이지만, 시스템이 그렇게 설계되었다면 그럴 수 있습니다.신호등을 만들어 신호등 버튼의 일부/전체가 작동하지 않도록 하는 것과 같은 것으로, 왜 버튼이 있는지 의문을 갖게 합니다.javascript는 가비지 수집 기능이 없기 때문에 자세히 조사하지 않습니다.

  1. 사양에 따르면 System.gc()는 GC를 실행해야 한다는 힌트이며 VM은 이를 무시할 수 있습니다.

"사기"가 뭐죠?컴퓨터는 단순히 힌트를 얻거나 무언가를 무시할 수 없습니다. 시스템의 의도에 따라 역동적일 수 있는 엄격한 행동 경로가 있습니다.적절한 답변에는 가비지 컬렉터가 실제로 구현 수준에서 수행 중인 작업이 포함됩니다. 따라서 가비지 컬렉터는 요청 시 수집을 수행하지 않습니다.이 기능은 단순한 기능입니까?제가 충족해야 할 조건이 있나요?어떤 조건입니까?

현재 상태로는 Java의 GC는 종종 여러분이 믿지 못하는 괴물처럼 보입니다.언제 올지, 사라질지, 어떻게 할지도 모릅니다.Garbage Collection이 명령별로 어떻게 동작하는지에 대해 보다 나은 지식을 가진 전문가도 있을 수 있지만, 대다수의 전문가는 단순히 "그냥 동작"하기를 바라고 있으며, 당신을 위해 작동하기 위해 불투명해 보이는 알고리즘을 신뢰해야 하는 것은 실망스러운 일입니다.

무언가를 읽는 것과 배우는 것 사이에는 큰 차이가 있습니다.시스템 간의 차이점을 실제로 확인하고 소스 코드를 보지 않고도 조작할 수 있습니다.이를 통해 자신감과 숙달감/이해감/통제감을 얻을 수 있습니다.

요약하자면, "이 기능은 아무 것도 하지 않을 수 있습니다.또, 무엇을 언제, 언제, 왜 하지 않는지, 그리고 왜 하지 않는지, 그리고 왜 하지 않는지에 대해서는 자세히 설명하지 않을 것입니다.이것은, 그 이면에 있는 의도가 합리적이더라도, 그것을 하려고 하는 것은 단순히 철학에 어긋나는 것임을 시사합니다."라는 대답에는 본질적인 문제가 있습니다.

It might be okay for Java GC to behave the way it does, or it might not, but to understand it, it is difficult to truly follow in which direction to go to get a comprehensive overview of what you can trust the GC to do and not to do, so it's too easy simply distrust the language, because the purpose of a language is to have controlled behavior up to philosophical extent(it's easy for a programmer, especially novices to fall into existential crisis from certain system/language behaviors) you are capable of tolerating(and if you can't, you just won't use the language until you have to), and more things you can't control for no known reason why you can't control them is inherently harmful.

Sometimes (not often!) you do truly know more about past, current and future memory usage then the run time does. This does not happen very often, and I would claim never in a web application while normal pages are being served.

Many year ago I work on a report generator, that

  • Had a single thread
  • Read the “report request” from a queue
  • Loaded the data needed for the report from the database
  • Generated the report and emailed it out.
  • Repeated forever, sleeping when there were no outstanding requests.
  • It did not reuse any data between reports and did not do any cashing.

Firstly as it was not real time and the users expected to wait for a report, a delay while the GC run was not an issue, but we needed to produce reports at a rate that was faster than they were requested.

Looking at the above outline of the process, it is clear that.

  • We know there would be very few live objects just after a report had been emailed out, as the next request had not started being processed yet.
  • It is well known that the cost of running a garbage collection cycle is depending on the number of live objects, the amount of garbage has little effect on the cost of a GC run.
  • That when the queue is empty there is nothing better to do then run the GC.

Therefore clearly it was well worth while doing a GC run whenever the request queue was empty; there was no downside to this.

It may be worth doing a GC run after each report is emailed, as we know this is a good time for a GC run. However if the computer had enough ram, better results would be obtained by delaying the GC run.

This behaviour was configured on a per installation bases, for some customers enabling a forced GC after each report greatly speeded up the production of reports. (I expect this was due to low memory on their server and it running lots of other processes, so hence a well time forced GC reduced paging.)

We never detected an installation that did not benefit from a forced GC run every time the work queue was empty.

But, let be clear, the above is not a common case.

These days I would be more inclined to run each report in a seperate process leaving the operating system to clear up memory rather then the garbage collector and having the custom queue manager service use mulple working processes on large servers.

GC efficiency relies on a number of heuristics. For instance, a common heuristic is that write accesses to objects usually occur on objects which were created not long ago. Another is that many objects are very short-lived (some objects will be used for a long time, but many will be discarded a few microseconds after their creation).

Calling System.gc() is like kicking the GC. It means: "all those carefully tuned parameters, those smart organizations, all the effort you just put into allocating and managing the objects such that things go smoothly, well, just drop the whole lot, and start from scratch". It may improve performance, but most of the time it just degrades performance.

To use System.gc() reliably(*) you need to know how the GC operates in all its fine details. Such details tend to change quite a bit if you use a JVM from another vendor, or the next version from the same vendor, or the same JVM but with slightly different command-line options. So it is rarely a good idea, unless you want to address a specific issue in which you control all those parameters. Hence the notion of "bad practice": that's not forbidden, the method exists, but it rarely pays off.

(*) I am talking about efficiency here. System.gc() will never break a correct Java program. It will neither conjure extra memory that the JVM could not have obtained otherwise: before throwing an OutOfMemoryError, the JVM does the job of System.gc(), even if as a last resort.

Maybe I write crappy code, but I've come to realize that clicking the trash-can icon on eclipse and netbeans IDEs is a 'good practice'.

Yes, calling System.gc() doesn't guarantee that it will run, it's a request to the JVM that may be ignored. From the docs:

Calling the gc method suggests that the Java Virtual Machine expend effort toward recycling unused objects

It's almost always a bad idea to call it because the automatic memory management usually knows better than you when to gc. It will do so when its internal pool of free memory is low, or if the OS requests some memory be handed back.

It might be acceptable to call System.gc() if you know that it helps. By that I mean you've thoroughly tested and measured the behaviour of both scenarios on the deployment platform, and you can show it helps. Be aware though that the gc isn't easily predictable - it may help on one run and hurt on another.

First, there is a difference between spec and reality. The spec says that System.gc() is a hint that GC should run and the VM is free to ignore it. The reality is, the VM will never ignore a call to System.gc().

Calling GC comes with a non-trivial overhead to the call and if you do this at some random point in time it's likely you'll see no reward for your efforts. On the other hand, a naturally triggered collection is very likely to recoup the costs of the call. If you have information that indicates that a GC should be run than you can make the call to System.gc() and you should see benefits. However, it's my experience that this happens only in a few edge cases as it's very unlikely that you'll have enough information to understand if and when System.gc() should be called.

One example listed here, hitting the garbage can in your IDE. If you're off to a meeting why not hit it. The overhead isn't going to affect you and heap might be cleaned up for when you get back. Do this in a production system and frequent calls to collect will bring it to a grinding halt! Even occasional calls such as those made by RMI can be disruptive to performance.

Some of what I am about to write is simply a summarization of what has already been written in other answers, and some is new.

The question "Why is it bad practice to call System.gc()?" does not compute. It assumes that it is bad practice, while it is not. It greatly depends on what you are trying to accomplish.

The vast majority of programmers out there have no need for System.gc(), and it will never do anything useful to them in the vast majority of use cases. So, for the majority, calling it is bad practice because it will not do whatever it is that they think it will do, it will only add overhead.

However, there are a few rare cases where invoking System.gc() is actually beneficial:

  1. When you are absolutely sure that you have some CPU time to spare now, and you want to improve the throughput of code that will run later. For example, a web server that discovers that there are no pending web requests at the moment can initiate garbage collection now, so as to reduce the chances that garbage collection will be needed during the processing of a barrage of web requests later on. (Of course this can hurt if a web request arrives during collection, but the web server could be smart about it and abandon collection if a request comes in.) Desktop GUIs are another example: on the idle event (or, more broadly, after a period of inactivity,) you can give the JVM a hint that if it has any garbage collection to do, now is better than later.

  2. When you want to detect memory leaks. This is often done in combination with a debug-mode-only finalizer, or with the java.lang.ref.Cleaner class from Java 9 onwards. The idea is that by forcing garbage collection now, and thus discovering memory leaks now as opposed to some random point in time in the future, you can detect the memory leaks as soon as possible after they have happened, and therefore be in a better position to tell precisely which piece of code has leaked memory and why. (Incidentally, this is also one of, or perhaps the only, legitimate use cases for finalizers or the Cleaner. The practice of using finalization for recycling of unmanaged resources is flawed, despite being very widespread and even officially recommended, because it is non-deterministic. For more on this topic, read this: https://blog.michael.gr/2021/01/object-lifetime-awareness.html)

  3. When you are measuring the performance of code, (benchmarking,) in order to reduce/minimize the chances of garbage collection occurring during the benchmark, or in order to guarantee that whatever overhead is suffered due to garbage collection during the benchmark is due to garbage generated by the code under benchmark, and not by unrelated code. A good benchmark always starts with an as thorough as possible garbage collection.

  4. When you are measuring the memory consumption of code, in order to determine how much garbage is generated by a piece of code. The idea is to perform a full garbage collection so as to start in a clean state, run the code under measurement, obtain the heap size, then do another full garbage collection, obtain the heap size again, and take the difference. (Incidentally, the ability to temporarily suppress garbage collection while running the code under measurement would be useful here, alas, the JVM does not support that. This is deplorable.)

Note that of the above use cases, only one is in a production scenario; the rest are in testing / diagnostics scenarios.

This means that System.gc() can be quite useful under some circumstances, which in turn means that it being "only a hint" is problematic.

(For as long as the JVM is not offering some deterministic and guaranteed means of controlling garbage collection, the JVM is broken in this respect.)

Here is how you can turn System.gc() into a bit less of a hint:

private static void runGarbageCollection()
{
    for( WeakReference<Object> ref = new WeakReference<>( new Object() ); ; )
    {
        System.gc(); //optional
        Runtime.getRuntime().runFinalization(); //optional
        if( ref.get() == null )
            break;
        Thread.yield();
    }
}

This still does not guarantee that you will get a full GC, but it gets a lot closer. Specifically, it will give you some amount of garbage collection even if the -XX:DisableExplicitGC VM option has been used. (So, it truly uses System.gc() as a hint; it does not rely on it.)

In my experience, using System.gc() is effectively a platform-specific form of optimization (where "platform" is the combination of hardware architecture, OS, JVM version and possible more runtime parameters such as RAM available), because its behaviour, while roughly predictable on a specific platform, can (and will) vary considerably between platforms.

Yes, there are situations where System.gc() will improve (perceived) performance. On example is if delays are tolerable in some parts of your app, but not in others (the game example cited above, where you want GC to happen at the start of a level, not during the level).

However, whether it will help or hurt (or do nothing) is highly dependent on the platform (as defined above).

So I think it is valid as a last-resort platform-specific optimization (i.e. if other performance optimizations are not enough). But you should never call it just because you believe it might help(without specific benchmarks), because chances are it will not.

  1. Since objects are dynamically allocated by using the new operator,
    you might be wondering how such objects are destroyed and their
    memory released for later reallocation.

  2. In some languages, such as C++, dynamically allocated objects must be manually released by use of a delete operator.

  3. Java takes a different approach; it handles deallocation for you automatically.
  4. The technique that accomplishes this is called garbage collection. It works like this: when no references to an object exist, that object is assumed to be no longer needed, and the memory occupied by the object can be reclaimed. There is no explicit need to destroy objects as in C++.
  5. Garbage collection only occurs sporadically (if at all) during the execution of your program.
  6. It will not occur simply because one or more objects exist that are no longer used.
  7. Furthermore, different Java run-time implementations will take varying approaches to garbage collection, but for the most part, you should not have to think about it while writing your programs.

ReferenceURL : https://stackoverflow.com/questions/2414105/why-is-it-bad-practice-to-call-system-gc

반응형