005JVM的垃圾回收机制是用来干嘛的?为什么要垃圾回收?
Posted csldm
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了005JVM的垃圾回收机制是用来干嘛的?为什么要垃圾回收?相关的知识,希望对你有一定的参考价值。
本文是个人内容总结,详细内容扫描二维码
1.前文回顾
脑子里一定要有一个会动的图:
1、启动一个线程执行业务代码(执行main方法就是开启一个main线程);
2、线程对应的程序计数器PC来记录程序执行到哪行字节码指令(线程与PC是1:1关系);
3、调用方法时会创建一个“栈帧”,放入线程对应的栈中(线程与栈、方法和栈帧都是1:1关系)
4、代码运行中创建的对象放在java堆内存(堆与JVM进程是1:1关系,堆是所有进程共享)
2.对象的分配与引用
1、启动main线程并创建与其对应的栈(称M栈),创建main方法对应的栈帧并压入栈
2、main方法调用loadReplicasFromDisk():创建方法的栈帧压入M栈,栈帧中会放入方法中的局部变量repliaManager
3、repliaManagerl.load():创建load对应栈帧,压入M栈
3.一个方法执行完毕后会怎样?
方法执行结束则栈帧出栈,线程结束则线程对应的栈也会被销毁。DS:这时候堆中的对象就失去了出栈方法中变量的引用,注意此时有可能还有别的线程中的变量在引用,不能认为他现在就是个垃圾对象。垃圾回收进行可达性分析,会分析所有栈中的变量对对象的引用,没有引用就是垃圾对象
4.我们创建的Java对象其实都是占用内存资源的
启动的Java系统本质就是一个JVM进程,进程本身也会占用内存资源
Java堆内存里创建的对象,都是占用内存资源的,而且内存资源有限
5.不再需要的那些对象应该怎么处理?
引用堆中对象的变量所在的方法执行完了,那么堆中的对象就成了“垃圾”,白白占用着堆内存空间
启动JVM进程会自动启动一个垃圾回收的Daemon线程。DS: 可以通过 jconsole来查看,线程里会有一个名字叫做“GC Daemon”的线程
6.本文小结
实例分析了程序执行过程:开启线程,创建栈,创建栈帧,创建对象,占用堆内存,引用对象,方法执行完,栈帧出栈,对象失去引用,垃圾收集器收集
7、问题总结
1、很多人在做数据导出的时候会在for循环中不断的创建对象,很容易造成堆溢出,这种大文件导出怎么破?
答:在循环外面创建一个对象,循环里对这个对象修改数据即可
2、方法执行完后,栈帧立马出栈,那么栈帧中的变量等数据是立马被回收掉么,还是需要等垃圾回收线程进行回收?
答:出栈就没了。DS:垃圾收集器收集的是堆中的对象,栈帧的存储空间分配在 Java 虚拟机栈之中,每一个栈帧都有自己的局部变量表、操作数栈和指向当前方法所属的类的运行时常量池的引用。
3、为什么堆中对象需要垃圾收集器进行收集,而栈帧中的内容不需要呢?
答:堆是所有线程共享的,对象能不能回收需要垃圾收集器使用算法进行判断。而栈帧是方法私有的,方法执行完,直接清除里面的内容,不需要考虑类似堆中对象的问题。
8、针对一些疑问补充内容
类的加载:将类的.class文件二进制数据读入内存(运行时数据区的方法区),然后在内存中(Hotspot是方法区)创建java.lang.Class的对象,该对象用来封装类的数据结构。比如ArrayList.class.getDeclaredFields();通过封装ArrayList类的数据结构Class对象,获取类声明的字段
以上是关于005JVM的垃圾回收机制是用来干嘛的?为什么要垃圾回收?的主要内容,如果未能解决你的问题,请参考以下文章