Java Memory Architecture (Model), Garbage Collection and Memory Leaks

转载 2015年11月19日 16:13:06


The above is the Java Memory Model for the Heap as well as the PermGen for any Java Application running in the Java Virtual Machine (JVM). The ratios are also provided to get a fair understanding of how the distribution of allowed memory is done across each of the generation types. All of the above is completely applicable up to Java release 1.7 (inclusive).The above is also known as the ‘Managed Area’ of the memory model.

In addition to the above, there is a Stack Area, which can be configured use the -Xss option. This area holds the references on the heap, native references, pc registers, code cache and local variables for all threads. This is also known as the ‘Native Area’ of the memory model.

Managed Area of the Java Memory Model (Java Memory Architecture)

[Young Generation/Nursery] Eden Space

All new objects are first created in the Eden Space. As soon as it reaches an arbitrary threshold decided by the JVM, a minor garbage collection (Minor GC) kicks in. It first removes all the non-referenced objects and moves referenced objects from the ‘eden’ and ‘from’ into the ‘to’ survivor space. Once the GC is over, the ‘from’ and ‘to’ roles (names) are swapped.

[Young Generation/Nursery] Survivor 1 (From)

This is a part of the survivor space (You may think of this a role in the survivor space). This was the ‘to’ role during the previous garbage collection (GC).

[Young Generation/Nursery] Suvrivor 2 (To)

This is also a part of the survivor space (You may think of this also a role in the survivor space). It is here, where during the GC, all the referenced objects
are moved to, from ‘from’ and ‘eden’ .

[Old Generation] Tenured

Depending on the threshold limits, which can be checked by using -XX:+PrintTenuringDistribution, which shows the objects (space in bytes) by age – Objects are moved from the ‘to’ Survivor space to the Tenured space. ‘Age’ is the number of times that it has moved within the survivor space. There are other important flags like, -XX:InitialTenuringThreshold, -XX:MaxTenuringThreshold and -XX:TargetSurvivorRatio which lead to an optimum utilization of the tenured as well as the survivor spaces. By setting -XX:InitialTenuringThreshold and -XX:MaxTenuringThreshold we allow an initial value and an maximum value for ‘Age’ while maintaining the percentage utilization in the ‘Survivor (To)’ as specified by the -XX:+NeverTenure and -XX:+AlwaysTenure, as they suggest are used to either never tenure an object (risky to use) and the opposite usage is to always tenure, which is to always use the ‘old generation’. The garbage collection that happens here is the major garbage collection (Major GC). This is usually triggered when the heap is full or the old generation is full. This is usually a ‘Stop-the-World‘ event or thread that takes over to perform the garbage collection. There is another type of GC named as the full garbage collection (Full GC) which involves other memory areas such as the permgen space.

Other important and interesting flags related to the overall heap are -XX:SurvivorRatio and-XX:NewRatio which specify the eden space to the survivor space ratio and old generation to the new generation ratio.

[Permanent Generation] Permgen space

The ‘Permgen’ is used to store the following information: Constant Pool (Memory Pool), Field & Method Data and Code. Each of them related to the same specifics as their name suggests.

Garbage Collection Algorithms

Serial GC (-XX:UseSerialGC): GC on Young Generation and Old Generation

Use the simple mark-sweep-compact cycle for young and tenured generations. This is good for client systems and systems with low memory footprint and smaller cpu

Parallel GC (-XX:UseParallelGC): GC on Young Generation and Old Generation

This used N threads which can be configured using -XX:ParallelGCThreads=N, here N is also the number of CPU cores. for garbage collection. It uses these N threads for GC in the Young Generation but uses only one-thread in the Old Generation.

Parallel Old GC (-XX:UseParallelOldGC): GC on Young Generation and Old Generation

This is same as the Parallel GC, except that it uses N threads for GC in both Old and Young Generation.

Concurrent Mark and Sweep GC (-XX:ConcMarkSweepGC): GC on Old Generaton

As the name suggest, the CMS GC minimzes the pauses that are required for GC. It is most useful to create highly responsive applications and it does GC only in the Old Generation. It creates multiple threads for GC that work concurrently with applications threads, which can be specified using the -XX:ParallelCMSThreads=n.

G1 GC (-XX:UseG1GC): GC on Young and Old Generation (By Dividing Heap into Equal Size Regions)

This is  a parallel, concurrent and incrementally compacting low-pause garbage collector. It was introduced with Java 7 with the ultimate vision to replace CMS GC. It divides the heap into multiple equal sized regions and then performs GC, usually starting with the region that has less live data – Hence, “Garbage First”.

Most Common Out of Memory Issues

The most common out of memory issues, which all Java Developers should know, so as to start debugging in the right earnest are as follows:

  • Exception in thread “main”: java.lang.OutOfMemoryError: Java heap spaceThis does not necessarily imply a memory leak – as it could be due to lesser space configured for the heap. Otherwise, in a long-lived application it could be due to unintentionally references being mentioned to heap objects (memory leak). Even the APIs that are called by the application could be holding references to objects that are unwarranted for. Also, in applications that make excessive use of finalizers, sometimes the objects are queued into a finalization queue. When such an application creates higher priority threads and that leads to more and more objects in the finalizaton queue, It can cause an Out-of-Memory.
  • Exception in thread “main”: java.lang.OutOfMemoryError: PermGen spaceIf there are many classes and methods loaded or if there are very many string literals created, especially through the use of intern() (From JDK 7, interned strings are no longer part of the PermGen) – then this type of error occurs. When this kind of error occurs, the text ClassLoader.defineClass might appear near the top of the stack trace that is printed.
  • Exception in thread “main”: java.lang.OutOfMemoryError: Requested array size exceeds VM limitThis again happens when the requested array size is greater than the available heap size. It may usually  occur due to programmatic errors during runtime, if an incredibly large value is requested for an array size.
  • Exception in thread “main”: java.lang.OutOfMemoryError: request <s> bytes for <r>. Out of swap space?
    It may usually be the root cause for a memory leak. It happens when either the Operating System does not have sufficient swap space or when Another Process hogs all the available memory resources on the system. In simple terms, it was unable to provide the request space from heap due to exhaustion of space. The message indicates the size ‘s’ (in bytes) of the request that failed and the reason ‘r’ for the memory request. In most cases the <r> part of the message is the name of a source module reporting the allocation failure, although in some cases it indicates a reason.
  • Exception in thread “main”: java.lang.OutOfMemoryError: <reason> <stack trace> (Native method)
    This indicates that a Native method has met with an allocation failure. The root cause was that the error occurred in JNI rather than in the code executing inside the JVM.When the native code does not check for memory allocation errors, then the application crashesinstead of going out of memory.

Definition of Memory Leak

“Think of memory leakage as a disease and the OutOfMemoryError as a symptom. But not all OutOfMemoryErrors imply memory leaks, and not all memory leaks manifest themselves as OutOfMemoryErrors. ”

In Computer Science, a memory leak is a type of resource leak that occurs when a computer program incorrectly manages memory allocations in such a way that memory which is no longer needed is not released. In Object-Oriented Programming, a memory leak may happen when an object is stored in memory but cannot be accessed by the running code.

Common Definitions of Memory Leak in Java:

A memory leak occurs when object references that are no longer needed are unnecessarily maintained.

Memory leak in Java is a situation where some objects are not used by application any more, but GC fails to recognize them as unused.

A Memory Leak appears when an object is no longer used in the program but is still referenced somewhere at a location that is not reachable. Thus, the garbage collector cannot delete it. The memory space used for this object will not be released and the total memory used for the program will grow. This will degrade performances over time and the JVM may run out of memory.

In a way, Memory Leak would occur when No Memory can be Allocated on the Tenured Space.

Some of the most common causes of Memory Leaks are:

  1. ThreadLocal Variables
  2. Circular and Complex Bi-Directional References
  3. JNI Memory Leaks
  4. Static Fields that are Mutable (Most Common)

I recommend the usage of Visual VM bundled with the JDK to start debugging your memory leak issues.

Common Debugging of Memory Leaks

  1. NetBeans Profiler
  2. Using the jhat Utility
  3. Creating a Heap Dump
  4. Obtaining a Heap Histogram on a Running Process
  5. Obtaining a Heap Histogram at OutOfMemoryError
  6. Monitoring the Number of Objects Pending Finalization
  7. Third Party Memory Debuggers

The common strategies or steps for going about debugging memory leak issues include:

  • Identify Symptoms
  • Enable Verbose Garbage Collection
  • Enable Profiling
  • Analyze the Trace

Wishing Happy Times, Fixing Java Memory Issues!

Reference: Java Memory Architecture (Model), Garbage Collection and Memory Leaksfrom our JCG partner Sumith Puri at the Techila Shots blog.

MFC学习(26)简单内存泄漏检测方法 解决 Detected memory leaks! 问题

最近在一个项目中,程序退出后都出现内存泄漏: Detected memory leaks! Dumping objects -> {98500} normal block at 0x05785AD0...
  • luoyouren
  • luoyouren
  • 2016年01月22日 09:10
  • 1010

内存溢出(Memory Overflow)和内存泄露(Memory Leak)的区别

内存泄漏指你用malloc或new申请了一块内存,但是没有通过free或delete将内存释放,导致这块内存一直处于占用状态 内存溢出指你申请了10个字节的空间,但是你在这个空间写入11或以上字节...
  • u013519020
  • u013519020
  • 2016年08月28日 19:09
  • 720


尽管这个概念已经让人说滥了 ,还是想简单记录一下, 以备以后查询。 运行一下代码 #ifdef _DEBUG #define DEBUG_CLIENTBLOCK new( _CLIENT_BLOC...
  • sesiria
  • sesiria
  • 2016年07月26日 22:26
  • 383


  • starshine
  • starshine
  • 2017年03月01日 10:34
  • 995


VLD为vc++下的内存泄露检测工具 1、首先下载安装vld,直接下载安装包,安装过程中会直接添加环境变量。 2、在安装目录下有vld.h, vldapi.h, vld.lib,
  • dalong277
  • dalong277
  • 2016年10月03日 00:02
  • 539

Java的内存结构(Memory Structure)和垃圾收集(Garbage Collection)图解

JVM 内存包含如下几个部分: Heap Memory 存放Java对象 Non-Heap Memory 存放类加载信息和其它meta-dataOther 存放JVM 自身代码等 在J...
  • u012719556
  • u012719556
  • 2013年11月05日 13:38
  • 622

关于tomcat在关闭时的memory leak日志信息的解释

关于tomcat在关闭时的memory leak日志信息的解释: 现象:在shutdown掉tomcat的时候出现一些如下异常: May 16, 2017 10:28:50 PM org....
  • penghaiping1001
  • penghaiping1001
  • 2017年05月23日 12:47
  • 840

内存泄露(Memory Leaks)简介

Java最大的一个优势是它的内存管理。你可以很方便地创建对象,而Java垃圾回收器(Garbage Collector)则会负责分配并释放内存。然而,实际情况并非如此简单,Java应用程序经常会发生内...
  • snarlfuture
  • snarlfuture
  • 2014年02月18日 21:25
  • 786

关闭tomcat时提示memory leak警告解决办法

原文地址: 当我们关闭tomcat 或者redeploy project时, 仔细看的...
  • cy104204
  • cy104204
  • 2013年11月21日 18:06
  • 2362

was内存溢出:native memory exhausted(本地溢出)

一、java.lang.OutOfMemoryError: native memory exhausted Java 虚拟机初始堆大小和最大堆大小不能盲目设置 以前碰到不少做J2EE应用的同事。 他们...
  • u012454773
  • u012454773
  • 2015年12月29日 17:57
  • 2480
您举报文章:Java Memory Architecture (Model), Garbage Collection and Memory Leaks