一、JDK1.7的JVM内存分布
分为虚拟机栈、本地方法栈、程序计数器====》线程安全的,堆、方法区
例如int a=1,int b=1,运行第一句时会在栈里面创建一个1,当运行第二句的时候直接用b指向已经存在的1.
堆分为新生代与老年代,新生代中默认情况下eden:s0:s1=8:1:1,老年代中(大对象,一个对象经历了15次GC就会移动到老年代)。
方法区中存放类信息,以及常量。
二、1.7中的GC
1、cms 他是在jdk1.5之后就有了
他是连续的内存块,标记清除后很有可能会造成内存不连续。缺点:很容易出现fgc造成程序卡死。因为fgc时其他运行线程将停止。
2、g1gc 是基于复制整理,他是将内存分为很多个小块。优点:不容易出现fgc,它的复制也很快。缺点:跨region管理起来比较麻烦。适用情况:高吞吐量比如双十一时。
三、JDK1.8 在内存方面的不同
无方法区,变为了元空间,string是存储于堆里面,常量和类信息存储于元空间。元空间不属于jvm,他是物理内存,当jvm关闭时内存也会释放。
去掉方法区的原因:方法区的回收率低,方法区中的类信息不好控制,如动态代理的时候。
四、类加载(ClassLoader)
分为五大步奏:加载=》连接=》初始化=》类的使用=》卸载
其中连接又分为=》验证=》准备=》解析
加载的字节流文件,前8个字节表示什么语言,coffebaby,后面就是版本
五、双亲委派模型
当运行一个main方法时,至少有三个classLoader
BootstrapClassLoader------------->ExtClassLoader---------------->ApplicationClassLoader
他们是继承关系,第一个是父类,他加载classPath/lib/*.jar。第二个加载一些扩展包classPath/ext/*.jar。第三个加载自己写的jar,或者外部引用的jar。
当加载一个string时,先去找Application,application去找他的父类ext,ext去找bootstrap,bootstrap找自己里面是否有这个类,有返回给Ext,依次返回回去,没有返回null。
可以自己写一个类加载器,继承自上面的即可。
tomcat中有十个以上的classLoader,都是以双亲委派模型来设计的。
目的是:避免同一个类的重复加载。