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正常回收,导致内存泄露。

原文地址:https://www.cnblogs.com/parent-absent-son/p/10610086.html