Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the default size of PermGen so small?

What would be the purpose of limiting the size of the Permgen space on a Java JVM? Why not always set it equal to the max heap size? Why does Java default to such a small number of 64MB? Are they trying to force people to notice permgen issues in their code by doing this?

If my app uses 85MB of permgen, then it might be safe to set it to 96MB but why set it so small if its just really part of the main heap? Wouldn't it be efficient to allow the JVM to use as much PermGen as the heap allows?

like image 634
djangofan Avatar asked Nov 20 '12 00:11

djangofan


People also ask

How can I increase my PermGen size?

To increase the PermGen memory change the value of the MaxPermSize variable, otherwise change the value of the Xmx variable. There are a lot of answers similar to this around but I found that this was the clearest and simplest phrased, very helpful.

What is PermGen size?

PermGen is the memory area for storing class data like static variable,byte code and etc. By default 64 Mb is allocated for PermGen.

How do I increase Metaspace size?

In Java 8 and onwards, we can set the initial and maximum size of Metaspace using the following commands: -XX:MetaspaceSize=N - sets the initial (and minimum size) of the Metaspace. -XX:MaxMetaspaceSize=N - sets the maximum size of the Metaspace.

Why does Java 8 remove PermGen space?

The main reason for removing PermGen in Java 8 is: It is very hard to predict the required size of PermGen. It is fixed size at startup, so difficult to tune. Future improvements were limited by PermGen space.


2 Answers

The PermGen is set to disappear in JDK8.

What would be the purpose of limiting the size of the Permgen space on a Java JVM?

Not exhausting resources.

Why not always set it equal to the max heap size?

The PermGen is not part of the Java heap. Besides, even if it was, it wouldn't be of much help to the application to fill the heap with class metadata and constant Strings, since you'd then get "OutOfMemoryError: Java heap size" errors instead.

like image 113
Frank Pavageau Avatar answered Sep 28 '22 06:09

Frank Pavageau


Conceptually to the programmer, you could argue that a "Permanent Generation" is largely pointless. If you need to load a class or other "permanent" data and there is memory space left, then in principle you may as well just load it somewhere and not care about calling the aggregate of these items a "generation" at all.

However, the rationale is probably more that:

  • there is potentially a benefit (e.g. from a processor cache point of view) from having all code/class metadata near together in memory space, and to guarantee this it is easier to allocate fixed sized area(s);
  • similarly, memory space where code/class metadata is stored potentially has certain "special" properties (notably, you don't want it to get paged out to disk if you can help it) and the system may not be able to set such properties on memory in a very granular way, so that it is more practical to have all "special" objects together in one (or a small number of) contiguous block or memory space;
  • having permanent objects all together helps avoid fragmenting the remaining memory space and again, the most practical way to do this is to allocate one contiguous block of memory of fixed size from the outset.

So as I see things, most of the time the reason for allocating a permanent "generation" is really for practical implementation reasons than because the programmer really cares terribly much.

On the other hand, the situation isn't usually terrible for the programmer either: the amount of permanent generation needed is usually predictable, so that you should be able to allocate the required amount with decent leeway. So if you find you are unexpectedly exceeding the allocation, this may well be a signal that "something serious is wrong".

N.B. It is probably the case that some of the issues that the PermGen originally was designed to solve are not such big issues on modern 64-bit processors with larger processor caches. If it is removed in future releases of Java, this is likely a sign that the JVM designers feel it has now "served its purpose".

like image 45
Neil Coffey Avatar answered Sep 28 '22 06:09

Neil Coffey