本文只是萌新初步了解JVM,本来打算写给自己看的,由于知识有限,写得不好甚至有错,欢迎指正
我们coding完后点击IDE的运行,程序就跑起来了,怎么回事?
首先我们写的源文件叫.java文件,然后点击IDE的运行在硬盘会生成.class字节码文件,接着Java虚拟机从硬盘加载.class字节码文件,再者内部操作和解析成电脑能识别的机器码,最后CPU执行
我们要重点关注的下面框框的部分,也就是JVM了

别那么着急,首先得看看JVM的体系结构:
这时上面框框的内容就可以稍微详细一点了
注意这时的图并不是完整且准确的,为了简便而改名或省略了,最后面会放出完整图的

那么,我们从上往下开始认识这些结构
负责加载.class字节码文件到 Java 虚拟机中
当然是动态加载的!即需要用到时才加载,这样节省了很多内存空间,防止内存溢出
那就是类的加载器了,类加载器默认有三种,还有一个自定义类加载器这里不讨论:

这里就有一个看起来高大尚的名词双亲委派,不用觉得很难,所谓的双亲委派指的是:
为了安全性
还有某个类被加载后就会把类的实例放到内存中,下次直接用内存中实例,不用再次加载了
加载过程分类三步:

类加载完后就开始给新生对象分配内存了,先来look look 虚拟机的内存结构把

浅绿色为线程共享
浅橙色为线程私有
其中:
简述一下内存分配
准备了两个类
public class BeanTest {
private int id;
private String name;
//各种Getters/Setters
}
public class JVMTest {
public static void main(String[] args) {
BeanTest beanTest = new BeanTest();
beanTest.setName("Howl");
System.out.println(beanTest.getName());
}
}
BeanTest beanTest = new BeanTest();,方法区没有这个类的元数据,动态加载beanTest.setName("Howl");,该实例根据指向去方法区找到对应类的元数据(方法表),获取对应函数的字节码地址当然是根据调配的指令顺序,依次执行程序指令拉
这里面有个技术需要讲一下下,JIT即时编辑器
JVM加载了.class文件后逐条读取并解析成机器码给CPU执行,我们当然不满足于此,有没有方法提高效率呢?
答案是有的,用 JIT即时编辑器
思路是这样的:
我们Sun公司使用的虚拟机是HotSpot,它采用计数器的方式(方法调用计数器,回边计数器)来判断是否为热点代码,当超过一定的数值时判断为热点代码

是时候放出稍微标准的图了,顺带提一下没有讲到的内容

程序在运行过程中,虚拟机会自动帮我们清理程序中不再需要的垃圾,减轻内存负担。
堆是垃圾回收的主战场,里面存放了大量实例
不像C语言,申请空间后需要free()来释放空间,但也不要因为有垃圾回收就不理会内存了
怎么判断是否为垃圾呢?
判断完就到回收垃圾了(回来填坑把)
over over over
配置元空间的初始值和最大值,设置堆空间的初始值和最大值。
-XX:MetaspaceSize=128M -XX:MaxMetaspaceSize=256M -Xms256m -Xmx256m
具体大小设置还得看环境,以及不敢自作聪明,回来填坑
参考
工具
原文:https://www.cnblogs.com/Howlet/p/12106762.html