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

转载 2012年04月17日 10:06:56

JVM 内存包含如下几个部分:

  • Heap Memory 存放Java对象
  • Non-Heap Memory 存放类加载信息和其它meta-data
  • Other 存放JVM 自身代码等

在JVM启动时,就已经保留了固定的内存空间给Heap内存,这部分内存并不一定都会被JVM使用,但是可以确定的是这部分保留的内存不会被其他进程使用。这部分内存大小由 -Xmx 参数指定。而另一部分内存在JVM启动时就分配给JVM,作为JVM的初始Heap内存使用。影响这个的参数是 -Xms

默认空余堆内存小于40%时,JVM 就会增大堆直到-Xmx的最大限制,可以由-XX:MinHeapFreeRatio指定。 
默认空余堆内存大于70%时,JVM 会减少堆直到-Xms的最小限制,可以由-XX:MaxHeapFreeRatio指定。

可以通过-XX:MaxPermSize设置Non-Heap大小.

GC 的年代划分

如果 -Xms指定的值比-Xmx的小,那么两者的差值就是Virtual内存值。随着程序的运行,Eden区、 Tenured区和Perm区会逐渐使用保留的Virtual空间。

JVM内存模型中Heap区分两大块,一块是 NEW Generation,另一块是Old Generation. 在NewGeneration中,有一个叫Eden的空间,主要是用来存放新生的对象,还有两个Survivor Spaces(from,to),它们的大小总是一样,它们用来存放每次垃圾回收后存活下来的对象。在OldGeneration中,主要存放应用程序中生命周期长的内存对象。在NewGeneration块中,垃圾回收一般用Copying的算法,速度快。每次GC的时候,存活下来的对象首先由Eden拷贝到某个SurvivorSpace, 当Survivor Space空间满了后, 剩下的live对象就被直接拷贝到OldGeneration中去。因此,每次GC后,Eden内存块会被清空。在OldGeneration块中,垃圾回收一般用mark-compact的算法,速度慢些,但减少内存要求.
垃圾回收分多级,0级为全部(Full)的垃圾回收,会回收OLD段中的垃圾;1级或以上为部分垃圾回收,只会回收NEW中的垃圾,内存溢出通常发生于OLD段或Perm段垃圾回收后,仍然无内存空间容纳新的Java对象的情况。

还有个Permanent Generation,主要用来放JVM自己的反射对象,比如类对象和方法对象等。关于这个区,它还提供String pool,看下面的例子:

[java] view plaincopy
  1. String first = "abc";   
  2. String second = new String ("abc");  

第一个对象存贮在Permanent Generation,而第二个对象存储在Heap里面。所以:

[java] view plaincopy
  1. String s = "abc";  
  2. String p = "abc";  

对象s和p指向同一个对象,这样效率大大提高。

 

内存申请过程如下:

  1. JVM 会试图为相关Java对象在Eden中初始化一块内存区域
  2. 当Eden空间足够时,内存申请结束。否则到下一步
  3. JVM 试图释放在Eden中所有不活跃的对象(这属于1或更高级的垃圾回收),释放后若Eden空间仍然不足以放入新对象,则试图将部分Eden中活跃对象放入Survivor区
  4. Survivor区被用来作为Eden及OLD的中间交换区域,当OLD区空间足够时,Survivor区的对象会被移到Old区,否则会被保留在Survivor区
  5. 当OLD区空间不够时,JVM 会在OLD区进行完全的垃圾收集(0级)
  6. 完全垃圾收集后,若Survivor及OLD区仍然无法存放从Eden复制过来的部分对象,导致JVM无法在Eden区为新对象创建内存区域,则出现”out of memory错误”


具体算法请参考:JDK5.0中JVM堆模型、GC垃圾收集详细解析 

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

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

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

JVM 内存包含如下几个部分: Heap Memory 存放Java对象 Non-Heap Memory 存放类加载信息和其它meta-dataOther 存放JVM 自身代码等 在JVM...
  • mylovepan
  • mylovepan
  • 2014年02月27日 11:16
  • 765

关于JAVA中的Garbage Collection和finalize()

关于JAVA中的Garbage Collection和finalize() Java的内存释放涉及到Garbage Collection的概念,那么到底什么是Garbage Collection呢?中...
  • youhaodeyi
  • youhaodeyi
  • 2005年12月16日 13:37
  • 2920

也谈谈Java的垃圾收集(garbage collection)

垃圾收集是Java语言非常显著的特点,不像C语言那样,老是要考虑什么数字的越界什么的。什么是垃圾(garbage)呢?“An object is considered garbage when it ...
  • autofei
  • autofei
  • 2011年04月21日 12:48
  • 10856

Garbage Collection: Automatic Memory Management in the Microsoft .NET Framework

Garbage Collection: Automatic Memory Management in the Microsoft...
  • bright60
  • bright60
  • 2007年12月02日 13:29
  • 706

Java Garbage Collection

1. 垃圾回收的意义  在C++中,对象所占的内存在程序结束运行之前一直被占用,在明确释放之前不能分配给其它对象;而在Java中,当没有对象引用指向原先分配给某个对象的内存时,该内存便成为垃圾。JVM...
  • DLUTBruceZhang
  • DLUTBruceZhang
  • 2013年06月03日 22:12
  • 2010

Java 垃圾收集(Garbage Collection)

原文:http://www.artima.com/insidejvm/ed2/gcP.html 垃圾收集 ----Bill Venners           Java虚拟机堆栈中存储运行中的java...
  • oliveevilo
  • oliveevilo
  • 2013年07月10日 21:35
  • 921

Java中的垃圾回收是如何工作的?(How Garbage Collection works in Java)

注:此文是在blogspot(被墙)上看到的,能翻墙的同学们自己去看(点此此处), 顺道可以看看一些其他的资料;不能翻墙的同学在此将就将就。 我读过许多关于Java垃圾回收的文章,其中...
  • redhat456
  • redhat456
  • 2011年09月22日 21:27
  • 3781

Python Garbage Collection 与 Objective-C ARC

转载请注明出处 http://www.jianshu.com/p/1cdfa6193854Python GC 与 Objective-C ARC提起GC(Garbage Collector)我们首先想...
  • u014205968
  • u014205968
  • 2017年04月06日 14:34
  • 2040

GC(Garbage Collection) 垃圾收集

GC(Garbage Collection) 垃圾收集         在堆中,垃圾收集器在对堆进行回收前,第一件事情就是要确定这些对象有哪些还“存活”着,哪些已经“死去”  1、引用计数算法: ...
  • anlidengshiwei
  • anlidengshiwei
  • 2015年01月19日 17:28
  • 646
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java的内存结构(Memory Structure)和垃圾收集(Garbage Collection)图解
举报原因:
原因补充:

(最多只允许输入30个字)