jvm知识点
一:java虚拟机的组成
1-程序计数器,线程私有,当前线程所执行的字节码的行号指示器。
2-java虚拟机栈,线程私有,用于存储局部变量表(八大基本类型和对象引用)、操作数栈、动态链接、方法出口等信息。
每一个方法从调用知道执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。
3-本地方法栈,类似于java虚拟机栈。虚拟机栈为虚拟机执行java方法服务。
本地方法栈为虚拟机使用到的native方法服务。
4-java堆,线程共享,存放对象实例。
5-方法区,用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器后的代码等数据。包含常量池。
二:对象的创建
检查--分配内存--初始化--对对象进行必要设置
三:hotspot的算法实现
判断对象是否存活使用使用的是可达性分析。
如果逐个遍历,需要耗费很多时间。
解决方式:使用OopMap数据结构来记录对象在栈的引用地址。这样就可以快速找到GC Roots的对象集合。
GC时,虚拟机会暂停,所以经常性GC和一次需要大量时间的GC。都不合适,这时就引入了安全点。
安全点:由于为每一条指令都生成OopMap需要大量的空间,所以只再特定的位置记录这些信息,这些位置成为安全点。
即程序执行时并非在所有地方都能停顿下来进行GC,只有在达到安全点时才能暂停。
虚拟机两种中断方式:1-抢先式中断,由虚拟机发起,所有线程全部中断,不在安全点上的线程,恢复运行至安全点上。
2-主动式中断,由线程去轮询是否中断的标志位,发现标识,就将线程暂停挂起。
四:并行与并发
1-并发的关键是:你有处理多个任务的能力,不一定同时。
2-并行的关键是:你拥有同时处理多任务的能力。(一般需要多核状态)。
在知乎上看到一个很好的比喻:
你吃饭吃到一半,电话来了,你一直到吃完了以后才去接,这就说明你不支持并发也不支持并行。
你吃饭吃到一半,电话来了,你停了下来接了电话,接完后继续吃饭,这说明你支持并发。
你吃饭吃到一半,电话来了,你一边打电话一边吃饭,这说明你支持并行。
后来的评论:并行是咽一口饭同时说一句话,而这光靠一张嘴是办不到的,至少两张嘴。
五:类加载的整个生命周期
加载--准备--验证--准备--解析--初始化--使用--卸载
六:内存泄露和内存溢出
内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;
内存泄露 memory leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。
内存泄露的种类:1-常发型内存泄露,2-偶发性内训泄露,3-一次性内存泄露,4-隐式内存泄露。
内存泄露的场景:1-静态集合类引起的内存泄露,2-当集合里面的对象属性被修改后,再调用remove方法时不起作用;
3-监听器,释放对象的时候却没有记住去删除这些监听器;
4-各种连接;
5-单例模式,如果单例对象持有外部对象的引用,那么这个外部对象将不能被jvm正常回收,导致内存泄露。