首页 > 代码库 > tomcat学习笔记
tomcat学习笔记
第一章 JVM原理
一、什么是JVM
JVM是Java Virtual Machine(Java虚拟机)的缩写。
JAVA语言的平台无关性如何实现:通过Java虚拟机,Java语言在不同平台上运行时不需要重新编译。Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。Java虚拟机在执行字节码时,把字节码解释成具体平台上的机器指令执行。这就是Java的能够“一次编译,到处运行”的原因。
上图为 JVM结构图
二、JAVA代码编译和执行过程
JAVA代码编译和执行包含如下三个过程:
Java源码编译机制
类加载机制
类执行机制
java源码编译机制
最终将.java文件编译生成.class文件
类加载机制
JVM的类通过ClassLoader及其子类来完成类加载的过程,类的层次关系和加载顺序可以由下图来描述:
(1)Bootstrap ClassLoader
负责加载$JAVA_HOME中jre/lib/rt.jar里所有的class,由C++实现,不是ClassLoader子类
(2)Extension ClassLoader
负责加载java平台中扩展功能的一些jar包,包括$JAVA_HOME中jre/lib/*.jar或-Djava.ext.dirs指定目录下的jar包
(3)App ClassLoader
负责记载classpath中指定的jar包及目录中class
(4)Custom ClassLoader
属于应用程序根据自身需要自定义的ClassLoader,如tomcat、jboss都会根据j2ee规范自行实现ClassLoader加载过程中会先检查类是否被已加载,检查顺序是自底向上,从Custom ClassLoader到BootStrap ClassLoader逐层检查,只要某个classloader已加载就视为已加载此类,保证此类只所有ClassLoader加载一次。而加载的顺序是自顶向下,也就是由上层来逐层尝试加载此类。
类执行机制
JVM是基于栈的体系结构来执行class字节码的。线程创建后,都会产生程序计数器(PC)和栈(Stack),程序计数器存放下一条要执行的指令在方法内的偏移量,栈中存放一个个栈帧,每个栈帧对应着每个方法的每次调用,而栈帧又是有局部变量区和操作数栈两部分组成,局部变量区用于存放方法中的局部变量和参数,操作数栈中用于存放方法执行过程中产生的中间结果。
三、JVM内存管理和垃圾回收
JVM栈有堆、栈、本地方法栈、方法区组成,结构如图
1)堆
所有通过new创建的对象的内存都在堆中分配,堆的大小可以通过-Xmx和-Xms来控制。
堆分为新生代、老年代和持久带,新生代分为Eden和Survivor(Survivor又分为from和to)
新生代:新建的对象都是用新生代分配内存,Eden空间不足的时候,会把存活的对象转移到Survivor中,新生代大小可以由-Xmn来控制,也可以用-XX:SurvivorRatio来控制Eden和Survivor的比例
老年代:用于存放新生代中经过多次垃圾回收仍然存活的对象
持久带(Permanent Space):主要存放所有已加载的类信息,方法信息,常量池等等。可通过-XX:PermSize和-XX:MaxPermSize来指定持久带初始化值和最大值。Permanent Space并不等同于方法区,只不过是Hotspot JVM用Permanent Space来实现方法区而已,有些虚拟机没有Permanent Space而用其他机制来实现方法区。
-Xmx:最大堆内存,如:-Xmx512m -Xms:初始时堆内存,如:-Xms256m -XX:MaxNewSize:最大年轻区内存 -XX:NewSize:初始时年轻区内存.通常为 Xmx 的 1/3 或 1/4。新生代 = Eden + 2 个 Survivor 空间。实际可用空间为 = Eden + 1 个 Survivor,即 90% -XX:MaxPermSize:最大持久带内存 -XX:PermSize:初始时持久带内存 -XX:+PrintGCDetails。打印 GC 信息 -XX:NewRatio 新生代与老年代的比例,如 –XX:NewRatio=2,则新生代占整个堆空间的1/3,老年代占2/3 -XX:SurvivorRatio 新生代中 Eden 与 Survivor 的比值。默认值为 8。即 Eden 占新生代空间的 8/10,另外两个 Survivor 各占 1/10
2)栈
每个线程执行每个方法的时候都会在栈中申请一个栈帧,每个栈帧包括局部变量区和操作数栈,用于存放此次方法调用过程中的临时变量、参数和中间结果。
-xss:设置每个线程的堆栈大小. JDK1.5+ 每个线程堆栈大小为 1M,一般来说如果栈不是很深的话, 1M 是绝对够用了的。
3)本地方法栈
用于支持native方法的执行,存储了每个native方法调用的状态
4)方法区
存放了要加载的类信息、静态变量、final类型的常量、属性和方法信息。JVM用持久代(Permanet Generation)来存放方法区,可通过-XX:PermSize和-XX:MaxPermSize来指定最小值和最大值
-------------------------------------------------------------------------------------------------------------------------------------
JVM垃圾回收
本文出自 “李娜渴死” 博客,请务必保留此出处http://zhoushuyu.blog.51cto.com/7125424/1944834
tomcat学习笔记