JVM介绍
1.方法区和堆区是所有线程共享的内存区域;而java栈、本地方法栈和程序计数器是运行时线程私有的内存区域。
2.Java栈又叫做jvm虚拟机栈
3.方法区(永久代)在 jdk8 中又叫做元空间 Metaspace
- 方法区用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器(JIT编译器,英文写作Just-In-Time Compiler)编译后的代码等数据。 虽然Java虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫做 Non-Heap(非堆),目的应该是与 Java 堆区分开来。
- 在JDK1.7之前运行时常量池逻辑包含字符串常量池存放在方法区, 此时hotspot虚拟机对方法区的实现为永久代
- 在JDK1.7 字符串常量池被从方法区拿到了堆中,这里没有提到运行时常量池,也就是说字符串常量池被单独拿到堆,运行时常量池剩下的东西还在方法区, 也就是hotspot中的永久代
- 在JDK1.8之后JVM 已经将运行时常量池从方法区中移了出来,在 Java 堆(Heap)中开辟了一块区域存放运行时常量池。同时在 jdk 1.8中移除整个永久代,取而代之的是一个叫元空间(Metaspace)的区域
- 元空间的本质和永久代类似,都是对JVM规范中方法区的实现。不过元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。因此,默认情况下,元空间的大小仅受本地内存限制。默认大概是用了20M的大小。
4.java代码执行流程:
java程序–(编译javac)–>字节码文件.class–>类装载子系统化身为反射类Class—>运行时数据区—>(解释执行)–>操作系统(Win,Linux,Mac JVM)
- 所有的栈和程序计数器并不会产生垃圾,所以不会有垃圾回收
- 我们所说的JVM调优是在方法区和堆里进行调优,99%是堆调优
- 注意:我们平时说的栈是指的Java栈,本地方法栈(native method stack) 里面装的都是native方法。
JVM生命周期
1.启动
通过引导类根加载器(bootstrap class loader)创建一个初始类(initial class)来完成的,这个类是由虚拟机的具体实现指定的.
2.执行
- 一个运行中的java虚拟机有着一个清晰的任务:执行Java程序;
- 程序开始执行的时候他才运行,程序结束时他就停止;
- 执行一个所谓的Java程序的时候,真真正正在执行的是一个叫做Java虚拟机的进程。
3.退出
- 程序正常执行结束
- 程序异常或错误而异常终止
- 操作系统错误导致终止
- 某线程调用Runtime类或System类的exit方法,或Runtime类的halt方法,并且java安全管理器也允许这次exit或halt操作
- 除此之外,JNI 规范描述了用 JNI Invocation API 来加载或卸载Java虚拟机时,Java虚拟机的退出情况
- jvm调优说的是“方法区”和“堆“,而”栈“、”本地方法栈“、”程序计数器“不存在垃圾回收一事
- 虚拟机试图使用最大内存为电脑内存的1/4, 而jvm初始化内存为1/64(-Xms1024m -Xmx1024m -XX:+PrintGCDetails)