-
JVM的组成:
- 堆内存:所有线程共享;在jvm启动时被创建,所有的对象空间分配都在该区域进行。
- 方法区:所有线程共享;又名永久代,保存类的信息、静态变量、常量和即时编译的代码等数据(jdk1.7中,永久代的字符串常量池移到堆中,1.8则撤销了永久代,引入了元空间)。
- java栈:线程私有内存;存储的为栈帧。(方法开始调用则会创建一个栈帧,保存了执行方法必须的信息,有局部变量表/操作数栈/动态链接/方法出口等。会产生两种异常:如果线程请求的栈深度大于虚拟机所允许的深度(如递归调用)会抛出StackOverflowError异常;如果虚拟机栈扩展到无法申请到足够的内存时,抛出OutOfMemoryError异常 )。
- 本地方法栈:线程私有;主要保存Native方法相关的数据,Native方法是非Java语言编写的方法。
JVM的启动过程:
1)首先使用 Java 命令启动JVM
2)其次进行JVM配置的装载——根据当前路径和系统的版本去寻找jvm.cfg文件,装载配置。
3)之后会根据加载的配置去寻找JVM.dll文件——JVM的主要实现文件。
4)通过该文件去初始化JVM,并获得相关的接口,比如JNIEnv接口,通过该接口实现findClass操作。
5)最后,通过相关接口(JNIEnv……),找到程序里的main方法,即可进入程序……
GC的几种回收方法:
1)引用计数法:在对象被其他所引用时计数器加一,而当引用失效时减一,无法处理循环引用情况,每次进行加减操作会浪费系统性能;
2)标记清除法:分为标记和清除两个阶段进行处理内存中的对象。空间碎片问题,垃圾回收空间是不连续的,不连续的内存空间的工作效率要低于连续的内存空间。
3)复制算法:将内存分为两块,每次使用其中一块,在垃圾回收时,将正在使用的内存中的存留对象复制到未被使用的内存块中去,之后去清除之前正在使用的内存块中的所有对象。反复交换两个内存角色。(Java中新生代的from/to空间使用该方法)
4)标记压缩法:在标记清除的基础上做了优化,把存活的对象压缩到内存一端,而后进行垃圾清理,(Java中老年代使用的就是该算法)
JVM内存参数设置:
-Xms:设置堆的最小空间大小;
-Xmx:设置堆的最大空间大小;
-XX:NewSize设置新生代最小空间大小;
-XX:MaxNewSize设置新生代最大空间大小;
-XX:PermSize 设置永久代最小空间;
-XX:MaxPermSize设置永久代最大空间大小;
-Xss:设置每个线程的堆栈大小。