发布时间:2023-06-17 16:00
注意点:
①方法出口:当调用完一个方法后,保存继续往下面执行的代码的位置指针。
②Math math = new Math(),中的new Math()存放在堆中,而math存放在栈中,只是开辟了一个内存空间而已。
③方法区:方法区中主要存放常量、静态变量、类信息等,比如private static final User user = new User(),静态变量user存放在方法区中,也是指向堆。
④本地方法栈:比如new Thread().start()中的start方法内部就用了private native void start0();这个本地方法,其本质使用C语言编写的,它会去C语言的库里面找对应的实现(.dll文件相当于java中的xx.jar)。如果执行到了本地方法,本地方法栈就存放本地方法在运行时的内存空间。
⑤GCRoot:
⑤堆内存:堆内存中有年轻代(1/3)和老年代(2/3),年轻代分成1个Eden Space(8/10)和2个Suvivor Space(2个1/10)。
假如部署了一个Web应用内,堆里面存储了大量的对象信息,当堆内存满了还要往Eden区加入时,这时会找出所有的GC Roots对象(即对象有不断的引用,最终成为一条链,这条链上的GC Roots就标记为非垃圾对象,将其复制到Survivor区中,而不在这条链上的对象就标记为垃圾对象,将会被销毁。比如程序结束时,堆里面的对象就没有引用了这时就不在这条链上,就被虚拟机回收了。)
⑥垃圾回收机制详解:当S0内存也满了的时候,会再次对Eden+S0区域进行minor gc垃圾回收,还是之前的原则将在链上的GCC Roots复制到S1中,其余的将会清理,同理,S1内存满了会对Eden+S0+S1进行minnor gc垃圾回收,每次垃圾回收,其对象的分代年龄(在对象头中)会+1,当S1中对象的分代年龄>=15(比如静态常量、spring容器中的bean等等)复制在老年代中,当老年代的内存满了会进行full gc即对整个堆包括方法区进行垃圾回收,但是当full gc回收不了什么垃圾时,就会出现OOM(Out of Memory)。
⑦STW:Stop the world,当虚拟机进行gc的时候会停止所有的用户进程。设计STW的目的是:如果在gc的时候,用户进程还在进行,就会去堆中找不断引用的对象链,一旦用户进程停止了,那些垃圾又得重新回收会导致很复杂、效率很低,因此是为了提高性能。
⑧虚拟机调优:最重要的就是评估内存模型,然后在调优。
分析内存模型:
调优过程:
⑨补充:进入老年代的另外一个条件
.class文件的字节码使用javap 命令进行反汇编的结果: