对于使用 C、C++ 的程序员来说,在内存管理领域,他们既是拥有最高权力的皇帝又是从事最基础工作的劳动人民——拥有每一个对象的“所有权”,又担负着每一个对象生命开始到终结的维护责任。对于 Java 程序员来说,在虚拟机自动内存管理机制的帮助下,不再需要为每一个 new 操作去写配对的 delete/free 代码,不容易出现内存泄漏和内存溢出,看起一切都很美好。不过,也正因为 Java 程序员把控制内存的权力交给了 Java 虚拟机,一旦出现内存泄漏和溢出,如果不了解虚拟机是怎样使用内存的,那排查错误将会成为一项异常艰难的工作。
 

一、Java虚拟机和Java内存区域概述

        1、虚拟机:
             定义:模拟某种计算机体系结构,执行特定指令集的软件。
             分为系统虚拟机(Virtual Box、VMware),进程虚拟机
        2、进程虚拟机
              并不会完整的模拟一个操作系统的运行环境,仅仅是提供特定指令集的运行环境。如JVM、Adobe Flash Player、FC模拟器
        3、高级语言虚拟机
              把特定指令集的范围限定为高级语言,如JVM、.NET CLR、P-Code(pascal)
        4、Java语言虚拟机
               可以执行Java语言的高级语言虚拟机,Java语言的虚拟机并不一定就可以成为JVM,譬如:Apache Harmony
        5、JavaTM虚拟机
               必须通过Java TCK(Technology Compatibility kit)的兼容性测试的Java语言虚拟机才能称为“JavaTM虚拟机
               JavaTM虚拟机并非一定要执行“Java”程序,他跟Java语言并没有严格相关,他跟java的编译文件class文件产生关联,即其他语言编译的符合格式的class文件也可以运行
               业界三大商用JVM:
                  Oracle HotSpot:JDK中使用的虚拟机,命名来自它的“热点代码探测”技术、
                  Oracle JRockit VM:、 
                  IBM J9 VM:
         6、共有设计,私有实现
                  《Java虚拟机规范》定义了概念模型,但同时也声明了这些概念不约束虚拟机的具体实现
         7、Java虚拟机运行时数据区
                   程序计数器、Java堆、Java虚拟机栈、本地方法栈、方法区
                   
           8、程序计数器(Program Counter Register)
                 一块较小的内存空间,它的作用可以看作是当前线程所执行的字节码的行号指示器
                 如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是Native方法,这个计数器值则为空。
                 此内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域
 
二、Java虚拟机栈和本地方法栈
         1、Java虚拟机栈的概念和特征
               线程私有,后进先出栈,存储栈帧,支撑Java方法的调用、 执行和退出
               可能出现StackOverflowError异常,如果栈被设计成可动态扩展,而在扩展的时候又申请不到足够的内存,还可能出现OutOfMemoryError异常
         2、本地方法栈的概念和特征
                线程私有,后进先出栈,作用是支撑Native方法的调用、执行和退出
                可能出现StackOverflowError和OutOfMemoryError异常
                有一些虚拟机如HotSpot将Java虚拟机栈和本地方法栈合并实现
         3、栈帧的概念和特征
                Java虚拟机栈中存储的内容,它被用于存储数据和部分过程结果的数据结构,同时也被用来处理动态链接、方法返回值和异常分派
                一个完整的栈帧包含:局部变量表、操作数栈、动态连接信息、方法正常完成和异常完成信息
                局部变量表:由若干个Slot组成,长度由编译期决定
                           单个Slot可以存储一个类型为Boolean,byte,char,short,float,reference和returnAddress的数据,两个Slot可以存储一个类型为long或double的数据
                           局部变量表用于方法间参数传递,以及方法执行过程中存储基础数据类型的值和对象的引用
                操作数栈:由若干个Entry组成,长度由编译期决定
 
三、Java堆
          1、Java堆的概念
                特征:全局共享,通常是Java虚拟机中最大的一块内存区域,作用是作为java对象的主要存储区域。JVMS明确要求该区域需要实现自动内存管理,即常说的GC,但并不限制采用哪种算法和技术去实现,可以在物理上不连续,可动态扩展,可能出现OutOfMemoryError
          2、栈与堆的讨论
                 
四、方法区和运行时常量池
          1、方法区的概念
                 全局共享,作用是存储Java类的结构信息,JVMS不要求该区域实现自动内存管理,但是商用虚拟机都能够自动管理该区域的内存
          2、运行时常量池的概念
                  全局共享,是方法区的一部分,作用是存储Java类文件常量池中的符号信息
          3、HotSpot方法区实现的变迁
                   在jdk1.2-jdk6,HotSpot使用永久代实现方法区
                   jdk7开始,HotSpot开始移除永久代的计划,符号表被移到Native Heap中,字符串常量和类的静态引用被移到Java Heap中
                   jdk8开始,永久代已被元空间(Metaspace)所代替
 
五、直接内存
        并非JVMS定义的标准Java运行时内存区域
        随JDK1.4中加入的NIO被引入,目的是避免在Java堆和Native堆中来回复制数据带来的性能损耗
        全局共享,能被自动管理,但是在检测手段上可能会有一些简陋
        可能出现OutOfMemoryError异常
 
六、垃圾回收机制(GC Garbage Collection)
       1、什么是垃圾回收机制
            ① 显示内存管理(C/C++):内存管理是程序开发者的职责
                  常见问题:
                   野指针:使用了一个指针,但是该指针指向的内存空间已经被free
                   内存泄露:内存空间已经申请,使用完毕后为主动释放,会一直占用内存
            ② 自动内存管理(Java/C#/一些脚本语言):内存空间由垃圾回收期自动管理
                    优点:增加了程序的可靠性,减小了内存泄露和野指针的情况,提高了程序员的效率
                    缺点:程序员无法控制GC的时间
                          判断哪些内存需要回收需要耗费系统开销
                          逻辑上的内存泄露依然会存在
 
       2、GC的工作原理
             找出不再使用的对象,进行回收,所有不再使用的对象都是垃圾
       3、GC算法:
            Ⅰ.引用计数法:
               给堆中的每一个对象增加一个引用计数器,当每一次创建一个对象并赋值给一个变量时,引用计数器就加1;当对象不再使用时(出了作用域),引用计数器减1,当引用计数器为0,对象就满足了垃圾回收的条件。
                特点:实现简单
                缺点:循环引用的垃圾无法回收
            Ⅱ.根搜索算法(Root Tracing):
                在主流的商用程序处理语言中,都是使用根搜索算法来判断随想是否存活的。
                该算法的基本思路就是通过一系列的名为GC Root的对象作为起点,从这些节点开始向下搜索,搜索所走的路径称为引用链(Reference chain)。当一个对象到GC Root之间没有任何引用链相连(用图论的话来说就是GC Roots到这些对象不可达)时,证明该对象是不可用的,GC程序即可回收这些对象
                专业术语:
                 Shallow size:就是最像本身占用的内存大小,也就是对象头加成员变量占用内存大小的总和
                 Retained size:是该对象自己的shallow size加上仅可以从该对象访问(直接或间接访问)的对象的shallow size之和。Retained size是该对象被GC之后所能回收的内存的总和
            Ⅲ.标记清除算法(Mark Sweep Algorithm):
               Dalvik使用标记清除算法实现垃圾回收
               1、mark:标记出被引用的对象
               2、sweep:清除哪些没有任何引用的对象
               所有引用默认标记为0,每清除掉一个Root时,系统将从其他Roots能到达的引用都标记为1,垃圾回收将标记为0的对象回收掉,然后所有的标记置位0,重新开始新一轮垃圾回收
       4、GC触发的时机
             申请Heap space失败后会触发GC,但此时已晚
             系统进入idle后一段时间会进行回收
             主动调用System.gc();进行回收

JVM自动内存管理学习笔记的更多相关文章

  1. C++内存管理学习笔记(7)

    /****************************************************************/ /*            学习是合作和分享式的! /* Auth ...

  2. C++内存管理学习笔记(5)

    /****************************************************************/ /*            学习是合作和分享式的! /* Auth ...

  3. C++内存管理学习笔记(6)

    /****************************************************************/ /*            学习是合作和分享式的! /* Auth ...

  4. JVM自动内存管理机制--读这篇就GO了

    之前看过JVM的相关知识,当时没有留下任何学习成果物,有些遗憾.这次重新复习了下,并通过博客来做下笔记(只能记录一部分,因为写博客真的很花时间),也给其他同行一些知识分享. Java自动内存管理机制包 ...

  5. C++内存管理学习笔记(4)

    /****************************************************************/ /*            学习是合作和分享式的! /* Auth ...

  6. C++内存管理学习笔记(3)

    /****************************************************************/ /*            学习是合作和分享式的! /* Auth ...

  7. C++内存管理学习笔记(2)

    /****************************************************************/ /*            学习是合作和分享式的! /* Auth ...

  8. JVM自动内存管理-Java内存区域与内存溢出异常

    摘要: JVM内存的划分,导致内存溢出异常的可能区域. 1. JVM运行时内存区域 JVM在执行Java程序的过程中会把它所管理的内存划分为以下几个区域: 1.1 程序计数器 程序计数器是一块较小的内 ...

  9. JVM自动内存管理机制——Java内存区域(下)

    一.虚拟机参数配置 在上一篇<Java自动内存管理机制——Java内存区域(上)>中介绍了有关的基础知识,这一篇主要是通过一些示例来了解有关虚拟机参数的配置. 1.Java堆参数设置 a) ...

随机推荐

  1. window下版本控制工具Git 客户端安装

    安装使用 1.下载msysgit http://code.google.com/p/msysgit/ 2.下载tortoisegit客户端安装 http://code.google.com/p/tor ...

  2. (原创)LAMP教程1-下载虚拟机软件

    (原创)LAMP教程1 从今天开始会在我的博客更新LAMP教程,第一章节就是安装虚拟机,因为不可能所有的人都有机会操作服务器,所以今天我打算教大家用虚拟机安装配置当下比较流行的框架,lamp. 好了费 ...

  3. Shell获取Aix/linux/unix机器上db2和os的信息并上传到指定服务器

    (之前写过一篇类似的文章,当时传输文件用的是ftp,因为项目觉得ftp不够安全所以这次换成了scp,同时对脚本的一些地方也做了一些调整) 其实做这个东西还是因为项目的需求,需要获取某些机器(目前主要是 ...

  4. NiuTrans 日记 1

    这些天把东北大学自然语言实验室的NiuTrans 系统搭建并按照例子将短语系统运行了一遍,写这个日记主要是为了以后能提醒自己在这其中遇到的问题. 环境:短语系统我是windows和linux都运行了, ...

  5. DzzOffice添加动态壁纸例子-Bing每日壁纸

    Bing每日壁纸介绍:bing网站每天会更新一张不同的精选图片. 此压缩包内的程序,可以自动同步更新cn.bing.com网站每天更新的图片,作为dzzoffice的壁纸使用.实现自动每天更换不同的云 ...

  6. C 实现的算法篇

    算法的定义:算法是解决实际问题的一种精确的描述方法,目前,广泛认同的定义是:算法的模型分析的一组可行的确定的和有穷的规则 算法的五个特性:有穷性,确切性,输入,输出,可行性.目前算法的可执行的步骤非常 ...

  7. CSS_网站配色参考方案

    http://www.cnblogs.com/QLeelulu/archive/2008/04/04/1136974.html   Shiny silver [#EEEEEE]       Reddi ...

  8. [Hive - LanguageManual] DML: Load, Insert, Update, Delete

    LanguageManual DML Hive Data Manipulation Language Hive Data Manipulation Language Loading files int ...

  9. 最大二位子数组和问题(homework-02)

    前面已经谈过最大一维子数组和问题,这里面扩展到二维. 一. 常规情况 一个矩形的数组,找到一个矩形的子数组有最大的元素和,求这个和. 1. 从朴素算法入手,枚举矩形数组的4个顶点,以此计算其数组和.同 ...

  10. Hibernate、Mybatis 通过数据库表反向生成java类和配置

    一.通过MyEclipse生成Hibernate类文件和hbm.xml文件,或者annotation文件    (转载孙宇老师的文章) 二.Mybatis生成实体类和配置文件: myeclipse下生 ...