一.JVM
java可以实现一次编写,到处运行。–>JVM帮我们处理不同硬件之间的差异
参数设置:
-X:执行的非标准的JVM参数,只有在部分HotSpot虚拟机下才能使用。
-XX:标准的JVM参数,可以使用于所有的HotSpot虚拟机。
-D:设置应用程序的参数
二.JVM组成
1.堆(线程共享)
(1)堆:所有创建的对象信息都放在了这个区域,堆也是JVM中最大的一块内存。Java堆是所有线程共享的一块区域,在JVM启动时创建。此内存区域存放的都是对象实例。JVM规范中说到:“所有的对象实例以及数组都要在堆上分配”。
(2)堆里的数据划分:
新生代:新创建的数据会在新生代,当经历了一定次数的GC(垃圾回收),依然存活下来的数据,会移动到老年代(HotSpot默认的垃圾回收次数是15)
老年代:存放的是经历了一定次数还存活的对象和大对象
【新生代又有三个区域:Eden、S0、S1(Eden+S0、Eden+S1)】
(3)-Xmx10m 设置堆空间最大值为10mb
-Xms10m 设置堆空间的最小值为10mb
面试题:为什么大对象会直接存到老年代?
答:因为大对象的创建和消耗所需要的时间比较多,所以性能也比较慢,如果存到新生代,那么可能会导致频繁的创建和消耗大对象,从而导致整个JVM运行效率的降低,所以就直接将大对象存到老年代。
2.JVM栈(线程私有、先进后出)
3.程序计数器(线程私有)
用来记录线程执行行号
4.本地方法栈(线程私有)
和JVM栈类似,只不过JVM栈是给java程序使用的,而本地方法栈是给本地方法(c/c++)使用的。
5.方法区(线程共享)
(1)在JDK1.8以前的HotSpot虚拟机中,方法区也被称为"永久代"(JDK1.8已经被元空间取代)。
元数据区(元空间是JDK1.8之后才有的,替代了方法区,它将自己的内容(静态属性、类元信息,运行时常量池)放入本地内存)
元空间移动到本地内存:《优点》不受JVM最大运行内存的限制,只和本地内存的大小有关.
(2)JDK1.8将字符串常量池放到了堆中
小结:线程私有:程序计数器、Java虚拟机栈、本地方法栈;线程共享:堆、方法区(元空间)
三.JVM类加载过程(Class Loading)
四.JVM双亲委派模型(JDK1.2)【Java类加载要符合双亲委派模型】
1.JVM加载类,子类并不会直接进行类加载,而是将任务交给父类,一层一层的进行传递。
如果找不到父类或者在父类中找不到此类,自己才会尝试加载。
启动类加载器:JDK底下的lib目录里的所有 jar包
扩展类加载器:lib–>ext目录里的所有jar包
2.双亲委派模型优点
(1)唯一性(一个加载之后另一个就不用加载了)
(2)安全性
3.破坏双亲委派模型
第一次:JDK1.2引入双亲委派模型,为了兼容老代码出现了第一次破坏双亲委派模型
第二次:它是双亲委派模型自身的缺点所导致第二次破坏,比如当父类出现了调用子类的方法的时候(双亲委派模型必须先加载父类再加载子类)
第三次:人们对于热更新和热加载的追求,导致了第三次双亲委派模型破坏。