一、走近Java
Java是一门结构严谨、面向对象的编程语言。摆脱了硬件平台的束缚,实现了一次编写,到处运行的理想;提供了一个相对安全的内存管理和访问机制,避免了绝大部分的内存泄漏和指针越界问题;实现了热点代码检测和运行时编译及优化,这使得Java应用能随着运行时间的增加而获得更高的性能。Java技术体系
Sun官方定义的Java技术体系包括以下几个组成部分1.Java程序设计语言2.各种硬件平台上的Java虚拟机3.Java API类库4.Class文件格式5.各商业机构和开源社区的第三方Java类库Java程序设计语言、Java虚拟机、Java API类库这三部分统称为JDK,JDK是用于支持Java程序开发的最小环境。
Java虚拟机、Java SE API子集这两部分统称为JRE,JRE是支持Java程序运行的标准环境。Java虚拟机发展史
1.Sun ClassicSun Classic VM是世界上第一款商用Java虚拟机,已停用。2.Sun HotSpot VM
Sun JDK和OpenJDK自带的虚拟机,也是目前使用范围最广的Java虚拟机。3.BEA JRockit/IBM J9 VM
除了Sun公司以外,其它组织、公司也研发过不少虚拟机实现,其中规模最大、最著名的就是BEA和IBM公司。4.Azul VM/BEA Liquid VM
5.Apache Harmony/Google Android Dalvik VM
6.Microsoft JVM
二、Java内存区域划分1.堆内存堆内存用于存放对象实例,在虚拟机启动时创建,被所有线程共享,是Java虚拟机所管理的内存中最大的一块。堆内存是垃圾收集器管理的主要区域,由于现在收集器基本都是采用的分代收集计算法,所以堆内存中可以细分为:新生代和老年代;再细致一点的有Eden空间、From Survivor空间、To Survivor空间等。2.栈内存
栈内存用于存放局部变量(基本数据类型和对象引用)、操作栈、方法返回等信息。线程私有,生命周期和线程一致。每个方法被执行时,虚拟机都会在栈内存中创建一个栈帧(Stack Frame),每个方法从被调用到执行完毕,就对应着一个栈帧在虚拟机中从入栈到出栈的过程。3.本地方法栈
本地方法栈与栈内存的作用非常相似,区别在于本地方法栈只为native方法服务。4.方法区
方法区是多个线程共享的内存区域,用于存放类信息、常量、静态变量、编译后的代码数据。(运行时常量池是方法区的一部分)。5.程序计数器
程序计数器是一块较小的内存区域,用于引导字节码解析顺序(如分支、循环、跳转、异常处理)。线程私有,各线程之间的计数器互不影响,独立存储。 三、垃圾收集器与内存分配策略垃圾收集(Garbage Collection,GC)栈内存、本地方法栈、程序计数器的生命周期和线程一致,当方法结束或线程结束时,内存就回收了。而堆内存和方法区则不一样,一个方法中多个分支需要的内存可能不一样,只有在程序处于运行期间才知道会创建哪些对象,这部分内存的分配和回收都是动态的,垃圾收集器所关注的就是这部分内存。垃圾收集算法
1.标记-清除算法2.复制算法3.标记-整理算法4.分代回收算法垃圾收集器
1.Serial收集器2.ParNew收集器3.Parallel Scavenge收集器4.Serial Old收集器5.Parallel Old收集器6.CMS收集器7.G1收集器 四、虚拟机性能监控与故障处理工具1.jdk的命令行工具jps 显示虚拟机的进程状况jstat 显示虚拟机中各种运行状态信息,如类装载、内存、垃圾收集、JIT编译等jinfo 显示虚拟机的配置信息jmap 用于生成堆转储快照(一般称为heapdump或dump文件)jhat 与jmap搭配使用,来分析jmap生成的堆转储快照jstack 用于生成当前线程正在执行的方法中堆栈的集合2.jdk的可视化工具
2.1.JConsole:Java监视与管理控制台2.2.VisualVM:多合一故障处理工具 五、调优案例分析 六、类文件结构计算机只认识0和1,所以我们写的程序需要经编译器翻译成由0和1构成的二进制格式才能由计算机执行。 七、虚拟机类加载机制虚拟机把class文件加载到内存,并对数据进行验证、准备、解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制。类的生命周期:加载、验证、准备、解析、初始化、使用、卸载。
加载、验证、准备、初始化和卸载这5个阶段的顺序是确定的,而解析阶段则不一定,它在某些特定情况下可以在初始化之后再开始。类加载的过程
类加载的过程包括加载、验证、准备、解析和初始化5个阶段。1.加载加载阶段,虚拟机需要完成3件事:a.通过一个类的全限定名来获取定义此类的二进制字节流。b.将这个字节流代表的静态存储结构转化为方法区的运行时数据结构。c.在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据访问入口。2.验证
验证的目的是为了确保Class文件中字节流包含的信息符合当前虚拟机的要求,并且不会危害虚拟机的自身安全。3.准备
准备阶段会在方法区给类变量分配内存并设置初始值,其中类变量的初始值为0,常量的初始值为程序设定的值。实例变量将会在对象实例化时随着对象一起分配在Java堆中。4.解析
解析阶段是虚拟机将常量池中的类、方法、属性替换为可直接引用的过程。5.初始化
初始化类变量,执行构造器。虚拟机规范规定了5种情况必须立即对类进行初始化(而加载、验证、准备自然在此之前执行)
1.new操作。2.反射。3.当初始化一个类时,如果该类的父类没有进行初始化,则先触发父类的初始化。4.当虚拟机启动时,用户需要指定一个要执行的主类(包含main方法的那个类)。5.JDK1.7,java.lang.invoke.MethodHandle。类与类加载器
类加载器虽然只用于实现类的加载动作,但它在Java程序中起到的作用却远远不限于类加载阶段。对于任意一个类,都需要由加载它的类加载器和这个类本身一同确立其在Java虚拟机中的唯一性。比较两个类是否相等,只有在这两个类是由同一个类加载器加载的前提下才有意义。