19

In case the heap is full, the JVM throws an OutOfMemoryError. But is it assured that a (full) garbage collection always takes place before such an exception is thrown?

This would mean that the memory is full only with strong referenced objects (or reachable by GC Roots) when the exception is thrown.

Edit: Assume the Sun JVM - HotSpot is in discussion.

Roman C
  • 49,761
  • 33
  • 66
  • 176
Random42
  • 8,989
  • 6
  • 55
  • 86
  • 1
    In java, its an "Out of Memory Error" – arshajii Sep 06 '12 at 11:09
  • @A. R. S.: I actually noticed this when I saw the comment of the 'outofmemoryexception' tag, which makes a reference to .NET. I have edited, thanks for the notice. – Random42 Sep 06 '12 at 11:10
  • I am curious on why exactly you are asking this question (not to say that it was not reasonable, but to learn what considerations you're making) – chiccodoro Sep 06 '12 at 11:40
  • @chiccodoro: When calling a method that fetches too much data from DB in memory, OutOfMemoryError is thrown. By calling the same method multiple times (in a loop) with pagination will the same Error be thrown if GC does not run between the subsequent calls or does GC surely run before the error is thrown? – Random42 Sep 06 '12 at 11:49

5 Answers5

23

The Java Machine Specification states in section 6.3 (emphasis mine):

OutOfMemoryError: The Java virtual machine implementation has run out of either virtual or physical memory, and the automatic storage manager was unable to reclaim enough memory to satisfy an object creation request.

So the JVM does give a guarantee that it will try what it can to free up memory through garbage collection before it throws an OOME.

The Scrum Meister
  • 29,681
  • 8
  • 66
  • 64
assylias
  • 321,522
  • 82
  • 660
  • 783
14

The garbage collector will usually be run before an OutOfMemoryError is thrown. However you might get an OOME without a GC if you

  • try to create a very large object (e.g. larger than the heap)
  • start a thread and there is not enough virtual memory or resources to start the thread.
  • older versions of Java would throw this error if you reached your maximum direct memory.
Alexander
  • 9,104
  • 1
  • 17
  • 41
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
7

You are not guaranteed that a full garbage collection has been performed, but that the VM has tried to make enough memory available through garbage collection. You could have found that in the API documentation for the OutOfMemoryError class:

Thrown when the Java Virtual Machine cannot allocate an object because it is out of memory, and no more memory could be made available by the garbage collector.

Note that there are cases where the garbage collector can decide that enough memory is not available without actually trying to discard unreferenced object instances. The most obvious example is if you try to allocate more memory in one go (e.g. a large byte array) than the max heap size. In this case, an OutOfMemoryError may be thrown without the garbage collector being run at all.

Brendan Long
  • 53,280
  • 21
  • 146
  • 188
jarnbjo
  • 33,923
  • 7
  • 70
  • 94
2

There's no guaranty that the last operation preceding OutOfMemoryError is garbage collection. Most probably not, since garbage collection would reduce the amount of used memory not increase it.

main--
  • 3,873
  • 1
  • 16
  • 37
Boris Pavlović
  • 63,078
  • 28
  • 122
  • 148
  • In this case, there is the possibility that from a 2 GB heap, maybe 0.5 GB consists of unreachable objects and the OutOfMemoryError is thrown even if, from my (the programmer's) POV, 1/4 of the heap is free. Could you suggest some reference for this? – Random42 Sep 06 '12 at 11:16
  • 2
    *"Most probably not, since garbage collection would reduce the amount of used memory not increase it"* unless there is no memory to reclaim... Several answers on SO seem to say the contrary (i.e. that the JVM will try to free resources with a GC before throwing an OOE). – assylias Sep 06 '12 at 11:20
2

There are other additional factors to consider besides what people have already answered, for example the garbage collection policy you are using. Consider the throughput garbage collection, this will throw an out of memory exception if too much time is being spent collecting and not enough memory is being freed (although the recent changes might have changed things). Having said all this I would not assume garbage collection occurs at any time within the execution of an application that I'm writing...

ramsinb
  • 1,985
  • 12
  • 17