JVM : 5 知识点归纳
Posted 鮀城小帅
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JVM : 5 知识点归纳相关的知识,希望对你有一定的参考价值。
1. 方法走完,引用消失,堆内存未必消失。个别在做报表导出的逻辑中,会在 for 循环里不断的创建对象,很容易造成对溢出。
面对上述的问题,建议不要在for 里创建对象,可以在外面搞一个对象, for 循环里对一个对象修改数据即可。
2. Java支持多线程,每个线程都有自己的 Java 虚拟机栈和本地方法栈。新建的实例在堆内存,实例变量也在堆内存。
3. 所谓出栈、入栈,入栈,就是你执行一个方法的时候,为这个方法创建一个栈帧入栈;出栈,就是方法执行完毕了,就会出栈。
4. 父类子类的情况下,加载顺序如下:
加载父类就是父类,除非用到子类才会加载子类;但是加载子类要初始化之前,必须先加载父类,初始化父类。
5. 类的实例化,是先加载类,再实例化对象。类加载器有三层,如果在第二层的类加载器可以加载这些类的话,就没有必要往上去找他的父类加载;其次,类只有用到的时候才加载到内存中,而new对象的时候肯定用到,需要先经历过类的所有过程才将类实例化。
6. Object Header (4字节) + Class Pointer(4字节) + Fields(看存放类型),因为JVM内存占用是 8 的倍数,所以结果要向上取整到 8 的倍数。
7. 静态成员变量,它在内存里,只有一份,就是属于类的。如果有多个线程并发修改,一定会有并发问题,可能导致数据出错。
8.在类加载机制中。如果是默认的类加载机制,那么是你的代码运行过程中,遇到什么类加载什么类。如果你要自己加载类,就需要写自己的类加载器。
9. 为什么必须要一级一级类加载器的网上招,直接从顶层类加载器开始找不就行了吗?
答: 每一层类加载器对某个类的加载,上推给父类加载器,到顶层类加载器,如果发现自己加载不到,再下推回子类加载器来加载,这样就可以保证绝对不会重复加载某个类。
而不直接从定层类加载请开始找,是因为类加载器本身就是做的父子关系模型。这种模型场景下,最底下的子类加载器,只能通过自己引用的父类加载器去找。如果直接找到顶层类加载器,不合适,那么顶层类加载器就必须硬编码规定了。
这就是一个代码设计思想,保证代码的可扩展性。
10. 在执行 new ReplicaManager 的时候加载 ReplicaManager 类。
11. 我们运行在机器上的系统,其实就是一个JVM进程,JVM进程会执行你系统里写好的那些代码
12.(1)class 文件分配内存是在准备阶段,而类的 class 对象也是在准备阶段分配内存空间。
(2)如果实例变量有初始值,那么实例变量得在创建类的实例对象时才会初始化;
(3)类的初始化阶段,仅仅是初始化类而已,跟对象无关,用 new 关键字才会构造一个对象处理
13. 双亲委派可以解决类重复加载的问题,虽然每个类加载器有不同的类加载路径,但不同类加载器的路径,一般是不会重叠的。
14. 自定义的类加载器本身是由系统加载器加载的,也就是说其本身是没有加密的,那么我拿到该类反编译就可以看到解密的 class 文件了。
因此,对 class 文件需要做特殊混淆处理,有商用的产品可以用。
15. 初始化时机就是对类的主动使用:调用静态方法时对类的主动使用的一种场景, main 方法本质上就是个 static 方法,没有调用的 main 方法和没有调用的 static 方法没区别!
包含main方法的类会优先加载,如果一个项目中有多个类都有 main 方法,并不会都加载,因为启动一个 jar 包,需要指定某个 main 主类,优先就是加载它。
16. 类的初始化需要执行静态代码块,给静态成员变量赋值,是因为这些数据都在方法区。类在方法区里,它在内存里,所以必须给他初始化,赋值。
启动类、扩展类和自定义加载器都已经指定了加载路径,所以不应该会有重复加载类的问题。但是双亲委派还是必要的,比如启动类加载器,可以通过一些方式指定加载其他目录的类,那额必须得走双亲委派,如果对那些特殊区域的类加载,走双亲委派,才能上推到启动类加载器去执行,不会重复加载。
以上是关于JVM : 5 知识点归纳的主要内容,如果未能解决你的问题,请参考以下文章