- Какие бывают типы OutOfMemoryError или из каких частей состоит память java процесса
- 1. java.lang.OutOfMemoryError: Java heap space
- 2. java.lang.OutOfMemoryError: PermGen space
- 3. java.lang.OutOfMemoryError: GC overhead limit exceeded
- 4. java.lang.OutOfMemoryError: unable to create new native thread
- java.lang.outofmemoryerror: java heap space | How to Fix?
- Introduction
- Understanding OutOfMemoryError in Java
- Other causes:
- Exception in thread “main” java.lang.outofmemoryerror: java heap space
- What is causing it?
- Stack vs Java Heap Space
- Solving java.lang.outofmemoryerror: java heap space error
- Increase Java Heap size in Java
- Conclusion
Какие бывают типы OutOfMemoryError или из каких частей состоит память java процесса
Если вы словили OutOfMemoryError, то это вовсе не значит, что ваше приложение создает много объектов, которые не могут почиститься сборщиком мусора и заполняют всю память, выделенную вами с помощью параметра -Xmx. Я, как минимум, могу придумать два других случая, когда вы можете увидеть эту ошибку. Дело в том, что память java процесса не ограничивается областью -Xmx, где ваше приложение программно создает объекты.
Область памяти, занимаемая java процессом, состоит из нескольких частей. Тип OutOfMemoryError зависит от того, в какой из них не хватило места.
1. java.lang.OutOfMemoryError: Java heap space
Не хватает место в куче, а именно, в области памяти в которую помещаются объекты, создаваемые программно в вашем приложении. Размер задается параметрами -Xms и -Xmx. Если вы пытаетесь создать объект, а места в куче не осталось, то получаете эту ошибку. Обычно проблема кроется в утечке памяти, коих бывает великое множество, и интернет просто пестрит статьями на эту тему.
2. java.lang.OutOfMemoryError: PermGen space
Данная ошибка возникает при нехватке места в Permanent области, размер которой задается параметрами -XX:PermSize и -XX:MaxPermSize. Что там лежит и как бороться с OutOfMemoryError возникающей там, я уже описал подробнейшим образом тут.
3. java.lang.OutOfMemoryError: GC overhead limit exceeded
Данная ошибка может возникнуть как при переполнении первой, так и второй областей. Связана она с тем, что памяти осталось мало и GC постоянно работает, пытаясь высвободить немного места. Данную ошибку можно отключить с помощью параметра -XX:-UseGCOverheadLimit, но, конечно же, её надо не отключать, а либо решать проблему утечки памяти, либо выделять больше объема, либо менять настройки GC.
4. java.lang.OutOfMemoryError: unable to create new native thread
Впервые я столкнулся с данной ошибкой несколько лет назад, когда занимался нагрузочным тестированием и пытался выяснить максимальное количество пользователей, которые могут работать с нашим веб-приложением. Я использовал специальную тулзу, которая позволяла логинить пользователей и эмулировать их стандартные действия. На определенном количестве клиентов, я начал получать OutOfMemoryError. Не особо вчитываясь в текст сообщения и думая, что мне не хватает памяти на создание сессии пользователя и других необходимых объектов, я увеличил размер кучи приложения (-Xmx). Каково же было мое удивление, когда после этого количество пользователей одновременно работающих с системой только уменьшилось. Давайте подробно разберемся как же такое получилось.
На самом деле это очень просто воспроизвести на windows на 32-битной машине, так как там процессу выделяется не больше 2Гб.
Допустим у вас есть приложение с большим количеством одновременно работающих пользователей, которое запускается с параметрами -Xmx1024M -XX:MaxPermSize=256M -Xss512K. Если всего процессу доступно 2G, то остается свободным еще коло 768M. Именно в данном остатке памяти и создаются стеки потоков. Таким образом, примерно вы можете создать не больше 768*(1024/512)=1536 (у меня при таких параметрах получилось создать 1316) нитей (см. рисунок в начале статьи), после чего вы получите OutOfMemoryError. Если вы увеличиваете -Xmx, то количество потоков, которые вы можете создать соответственно уменьшается. Вариант с уменьшением -Xss, для возможности создания большего количества потоков, не всегда выход, так как, возможно, у вас существуют в системе потоки требующие довольно больших стеков. Например, поток инициализации или какие-нибудь фоновые задачи. Но все же выход есть. Оказывается при программном создании потока, можно указать размер стека: Thread(ThreadGroup group, Runnable target, String name,long stackSize). Таким образом вы можете выставить -Xss довольно маленьким, а действия требующие больших стеков, выполнять в отдельных потоках, созданных с помощью упомянутого выше конструктора.
Более подробно, что же лежит в стеке потока, и куда уходит эта память, можно прочитать тут.
Конечно, вам может показаться данная проблема слегка надуманной, так как большинство серверов нынче крутиться на 64-битной архитектуре, но все же считаю данный пример весьма полезным, так как он помогает разобраться из каких частей состоит память java-процесса.
java.lang.outofmemoryerror: java heap space | How to Fix?
How to solve java.lang.outofmemoryerror: java heap space or exception in thread “main”? Know reasons caused by and how to solve it guide.
Introduction
In Java JVM allocates a defined memory size for storing objects created during program execution known as Java Heap Space. Along with it, JVM allocates another memory called PermGen space: permanent generation space.
However, we can change the default size with the JVM options.
Most importantly, Oracle completely removed this memory space in the JDK 8 release.
Memory space in the JDK 8 release
Understanding OutOfMemoryError in Java
There most common reason for this error is simple –
If we try to fit a large application into a smaller space. In other words, the application just requires more Java heap space than available to it to operate normally.
Other causes:
- Spikes in usage/data volume- The application was designed to handle a certain amount of users or a certain amount of data. When the number of users or the volume of data suddenly spikes and crosses the expected limit. The operation which functioned normally before the spike ceases to operate and triggers the OutOfMemoryError.
- Memory leaks- A particular type of programming error will lead your application to constantly consume more memory. Every time the leaking functionality of the application is used it leaves some objects behind in the Java heap space. Over time the leaked objects consume all of the available heap space and trigger the already familiar OutOfMemoryError.
Exception in thread “main” java.lang.outofmemoryerror: java heap space
Exception in thread "main" java.lang.OutOfMemoryError
What is causing it?
Generally, bad programming results in OutOfMemoryError. OutOfMemoryError usually means that we’re doing something wrong, either holding onto objects too long or trying to process too much data at a time. Sometimes, it indicates a problem that’s out of our control, such as a third-party library that caches strings, or an application server that doesn’t clean up after deploys.
GC Overhead limit exceeded- This error indicates that the garbage collector is running all the time and the Java program is making very slow progress. If such an event occurs then an OutOfMemoryError is thrown.
Stack vs Java Heap Space
Heap Space
Whenever we create an object, it’s always created in the Heap space.
Stack Memory
Java Stack memory is used for the execution of a thread. It also contains method references.
Note: String Pool is also a part of Java Heap Memory.
Solving java.lang.outofmemoryerror: java heap space error
Increase Java Heap size in Java
The default size of Heap space in Java is 128MB on most of 32 bit Sun’s JVM but it highly varies from JVM to JVM.
For instance, the default maximum and start heap size for the 32-bit Solaris Operating System (SPARC Platform Edition) is -Xms=3670K and -Xmx=64M. And default values of heap size parameters on 64-bit systems have been increased up by approximately 30%.
Also, if we are using a throughput garbage collector in Java 1.5 default maximum heap size of JVM would be Physical Memory/4, and the default initial heap size would be Physical Memory/16.
Another way to find the default heap size of JVM is to start an application with default heap parameters and monitor using JConsole. It is available on JDK 1.5 onwards, on the VMSummary tab, you will be able to see the maximum heap size.
Moreover, we can increase the size of java heap space based on our application need and it is always recommended to avoid using default JVM heap values. Therefore, if our application is large and lots of objects are created. We can change the size of heap space by using JVM options -Xms and -Xmx. Here, Xms denotes the starting size of Heap while -Xmx denotes the maximum size of Heap in Java.
There is another parameter called -Xmn. It denotes the size of the new generation of Java Heap Space. The only thing is we can’t change the size of Heap in Java dynamically. We can only provide the Java Heap Size parameter while starting JVM.
Conclusion
We hope you got your error resolved. Let us know by commenting if you need any help or have any questions.
If this article helped you feel free to share. Keep reading and sharing. Kudos!!