请简述java的内存回收机制-简述java内存回收机制
java 中的数据类型分为八种基本类型和引用类型,可以作为成员变量(放堆中),局部变量(放虚拟机栈中),静态变量(放方法区中).
jvm内存划分:
堆:存放成员变量请简述java的内存回收机制请简述java的内存回收机制,线程共享
虚拟机栈: 存放局部变量,线程私有
方法区:存放静态变量和类信息,线程共享
程序计数器 :记录程序运行的位置,线程私有
本地方法栈: 存放native相关信息.线程私有
堆是线程共享的内存空间,虚拟机栈是线程私有的内存空间,每个线程都有自己的虚拟机栈空间
为什么用垃圾回收机制?
防止内存溢出,内存溢出指不释放内存,导致内存满了,申请不了新的空间,导致整个程序运行瘫痪.
GC(垃圾回收)机制回收的是堆和方法区中的内存,主要是堆内存.
1.方法区内存: 静态变量的生命周期和类的声明周期相同,当类被销毁时,GC机制就会回收对应的静态变量.
2.堆内存: 1.先用**"可达性分析**"的方法确认哪些对象需要被回收
2.然后根据对象的声明周期进行回收:
如果是刚出生的对象,将不需要回收的对象复制到另一片内存空间,最后将需要回收的整片空间回收掉,这样做的好处是避免了"内存碎片"的产生,内存碎片是指回收掉之后的可利用空间,但是这些内存空间断断续续,使得无法在这些空间上申请连续的空间,缺点是会占用更多的内存空间.
对于已经存活很久的对像,因为经过了很多轮的可达性分析说明这些对象存活周期较长,所以直接进行采用整理的方式回收掉对象.整理是先将对象回收掉,再用剩下的对象补齐产生的内存碎片,优点是不会产生内存碎片和占用额外空间,但是效率更低.
可达性分析: 使用有向图的结构,图中的节点是对象的引用,回收机制遍历每个线程的栈帧,如果遍历不到对象的引用,说明对象需要回收.
为什么不能用计数法?
计数法是指将count设置为对象的引用次数,如果引用次数为0就会销毁对象,这样会产生一个问题,比如引用类型作为成员变量,然后把将引用类型作为成员变量的引用置为null,这样里面的作为成员变量的引用就调用不到了,此时count为0,但是这个对象永远都调用不到,"可达性分析"方法避免了这个问题的产生.
虚拟机栈中是如何处理内存的呢?
每个线程都有一个虚拟机栈,每个方法代表一个栈帧,调用方法就入栈,方法使用完毕就出栈,自动将局部变量占有的内存释放.
深拷贝:对一个对象的修改不会影响到另一个对象
浅拷贝:对一个对象的修改会影响到另一个对象
如何做到深拷贝?
将属性为引用类型的成员变量递归地创建新的对象,代替被复制的引用对象.
双亲委派模型:通过类加载器先找jdk自带的类,再找在应用层自己定义的类.