`

Java基础恶补——内存管理、垃圾回收

    博客分类:
  • Java
GC 
阅读更多

 

----------------------------------------------------------------------------------------------

参考:《Java2编程详解》

http://www.ibm.com/developerworks/cn/java/l-JavaMemoryLeak/

----------------------------------------------------------------------------------------------

 

要点

  • 内存模型:
    a) 浅谈Java内存模型 (这篇文章非常好)
  • 内存管理:
    a) 大多数的运行时系统都有一个堆管理器 ,动态地维护堆的状态,使尽可能多的内存可以使用。
    b) 堆管理器所要解决的主要问题之一为碎块问题,一般情况下,堆的管理是通过跟踪自由内存块列表、已分配的内存块列表来完成的。
    c) 堆管理器使用的策略或技术:首次适合策略、合并、压缩。
  • d) JVM内存管理:深入Java内存区域与OOM(这篇文章也很好)
  • 垃圾回收:
    a) 垃圾回收是对所有已不再需要或不再引用的已分配的内存对象,在不进行显式释放的情况下回收到自由块列表中的一种技术。
    b) 2种常见的垃圾收集技术:引用计数标记并清除
  • JVM堆管理器要点:
    a) 包含2个堆:一个堆包含了类信息和方法的固定表,该堆无垃圾收集;另一个包含句柄表和对象实例;
    b) 我们无需进行显式的内存释放,可以通过调用 System.gc() 方法人为地运行垃圾收集器。
  • JVM垃圾收集器使用的是停止并拷贝(stop-and-copy) 算法;
    优点:速度快;缺点:不适用于实时应用程序。
  • 理解GC的工作原理:可以将对象考虑为有向图的顶点,将引用关系考虑为图的有向边,有向边从引用者指向被引对象。另外,每个线程对象可以作为一个图的起始顶点,例如大多程序从main进程开始执行,那么该图就是以main进程顶点开始的一棵根树。在这个有向图中,根顶点可达的对象都是有效对象,GC将不回收这些对象。如果某个对象 (连通子图)与这个根顶点不可达(注意,该图为有向图),则认为这个(这些)对象不再被引用,可以被GC回收。
     
  • GC相关调整的目标
  • Java GC 日志详解,    JVM GC日志时间问题
  • 一次Java垃圾收集调优实战

 

相关问题

1. Q: Java 对象的存储区域

    A:  有6个地方可以保存数据:
         1) 寄存器

         这是最快的保存区域,因为它位于和其他所有保存方式不同的地方:处理器内部。然而,寄存器的数量十分有限,所以寄存器是根据需要由编译器分配。我们对此没有直接的控制权,也不可能在自己的程序里找到寄存器存在的任何踪迹。
         2) 堆栈

         驻留于常规RAM(随机访问存储器)区域,但可通过它的“堆栈指针”获得处理的直接支持。堆栈指针若向下移,会创建新的内存;若向上移,则会释放那些内存。这是一种特别快、特别有效的数据保存方式,仅次于寄存器。创建程序时,Java编译器必须准确地知道堆栈内保存的所有数据的“长度”以及“存在时间”。这是由于它必须生成相应的代码,以便向上和向下移动指针。这一限制无疑影响了程序的灵活性,所以尽管有些Java数据要保存在堆栈里——特别是对象句柄,但Java对象并不放到其中。
          3) 堆

          一种常规用途的内存池(也在RAM区域),其中保存了Java对象。和堆栈不同,“内存堆”或“堆”(Heap)最吸引人的地方在于编译器不必知道要从堆里分配多少存储空间,也不必知道存储的数据要在堆里停留多长的时间。因此,用堆保存数据时会得到更大的灵活性。要求创建一个对象时,只需用new命令编制相关的代码即可。执行这些代码时,会在堆里自动进行数据的保存。当然,为达到这种灵活性,必然会付出一定的代价:在堆里分配存储空间时会花掉更长的时间!
           4) 静态存储

           这儿的“静态”(Static)是指“位于固定位置”(尽管也在RAM里)。程序运行期间,静态存储的数据将随时等候调用。可用static关键字指出一个对象的特定元素是静态的。但Java对象本身永远都不会置入静态存储空间。
           5) 常数存储

           常数值通常直接置于程序代码内部。这样做是安全的,因为它们永远都不会改变。有的常数需要严格地保护,所以可考虑将它们置入只读存储器(ROM)。
           6) 非RAM存储

           若数据完全独立于一个程序之外,则程序不运行时仍可存在,并在程序的控制范围之外。其中两个最主要的例子便是“流式对象”和“固定对象”。对于流式对象,对象会变成字节流,通常会发给另一台机器。而对于固定对象,对象保存在磁盘中。即使程序中止运行,它们仍可保持自己的状态不变。对于这些类型的数据存储,一个特别有用的技巧就是它们能存在于其他媒体中。一旦需要,甚至能将它们恢复成普通的、基于RAM的对象。Java 1.1提供了对Lightweight persistence的支持。未来的版本甚至可能提供更完整的方案。
                                                                                                                 ——《Think in Java》Chapter 2

 

2. Q: JVM的内存区域组成?
    A:  Java把内存分两种:一种是栈内存,另一种是堆内存。

         1) 栈内存:存放在函数中定义的基本类型变量和对象的引用变量;

         2) 堆内存:存放由new创建的对象和数组;堆分为三个区:New、Old 和 Permanent

         在堆中分配的内存由GC来管理;新创建的对象被分配到New区,当该区被填满时会被GC辅助线程移到Old区,当Old区也填满了会触发GC主线程遍历堆内存里的所有对象。Old区的大小等于Xmx减去-Xmn。

         堆的优点是可以动态分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的;缺点就是要在运行时动态分配内存,存取速度较慢;

         栈的优点是存取速度比堆要快,缺点是存在栈中的数据大小与生存期必须是确定的无灵活性。

 

3. Q: GC是什么?为什么要有GC?
    A:  GC是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃。

          Java 程序员不用担心内存管理,因为垃圾收集器会自动进行管理。要请求垃圾收集,可以调用下面的方法之一:  

        System.gc() 
      Runtime.getRuntime().gc() 

 

4. Q: 垃圾回收器的基本原理是什么?垃圾回收器可以马上回收内存吗?有什么办法主动通知虚拟机进行垃圾回收?
    A:  对于GC来说,当程序员创建对象时,GC就开始监控这个对象的地址、大小以及使用情况。通常,GC采用有向图的方式记录和管理堆中的所有对象。通过这种方式确定哪些对象是"可达的",哪些对象是"不可达的"。当GC确定一些对象为"不可达"时,GC就有责任回收这些内存空间。

         垃圾回收器可以马上回收内存。

         程序员可以手动执行System.gc(),通知GC运行,但是Java语言规范并不保证GC一定会执行。

 

5. Q: 垃圾回收的优点和原理。考虑2种回收机制。
    A:  Java语言中一个显著的特点就是引入了垃圾回收机制,使C++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候不再需要考虑内存管理。由于有个垃圾回收机制,Java中的对象不再有"作用域"的概念,只有对象的引用才有"作用域"。垃圾回收可以有效的防止内存泄露,有效的使用可以使用的内存。垃圾回收器通常是作为一个单独的低级别的线程运行,不可预知的情况下对内存堆中已经死亡的或者长时间没有使用的对象进行清除和回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收。

         回收机制有分代复制垃圾回收和标记垃圾回收,增量垃圾回收。

 

6. Q: 举例说明一个典型的垃圾回收算法。
    A:  1) 引用计数

          要求堆中的每个对象实例都有一个称为引用计数的字段,当分配时计数+1、超出或销毁时-1,当引用计数为0时其空间可回收。
          引用计数优点:回收速度快;

          缺点:引起运行时系统性能下降。
          2) 标记并清除

          要求每个对象都包含一个位字段,称为标记位,或在算法运行时建立一个外部数组以存放标记位。该算法从遍历堆中所有已分配的内存块开始,重新设置块的标记位,检查所有指向堆中对象的字段和变量,将被引用对象的标记位设置为真,然后找出所有未标记对象,将其放到自由块列表中来回收空间。
          标记并清除优点:存储开销较低且不会影响运行时的执行性能;

          缺点:当内存垃圾收集器运行时可能会占用很长时间。

  • 大小: 3.6 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics