1.2 垃圾回收jvm的内存结构中主要存在五个区域,分别是:
程序计数器:占用内存较小,可以看作是当前线程的行号指示器虚拟机栈:每个方法执行的时候都会创建一个栈帧,用来存储局部变量表、操作数栈、动态链接、方法返回地址等信息。每一个方法从调用到执行完成的过程,都对应一个栈桢在虚拟机栈中的入栈和出栈本地方法栈:与虚拟机栈类似,虚拟机栈是为了虚拟机能够执行方法,而本地方法栈是为了虚拟机能够找到方法方法区:方法区和堆类似,也是一块被所有线程共享的区域。里面存放的是已经被虚拟机加载过的类信息、常量、静态变量堆:占用内存最大的一块区域,存放的是各种引用类型的变量,也是被所有线程共享的
创建各种引用数据类型的变量的时候,虚拟机都会在堆中开辟一块内存空间用于存放;当这块内存空间不再被任何变量引用的时候,这块内存就变成了垃圾
Java引入了了垃圾回收机制Garbage Collection,GC;用来处理垃圾,不需要我们手动的区释放空间
程序计数器、虚拟机栈、本地方法栈、这三个区域是线程私有的,不需要进行垃圾回收
堆、方法区是线程共享的,需要进行垃圾回收
1.3 判断对象是否可以被垃圾回收的两种算法可以手动使用System.gc()方法,通知GC执行,但是GC不是一定会执行
Object类中的finalize()方法,当对象被回收之前会执行该方法;但是如果程序运行结束之前,虚拟机没有进行垃圾回收,那么finalize()将会没有机会被执行
1.3.1 引用计数器算法主要有两种:
引用计数器算法可达性分析算法
1.3.2 可达性分析算法在类中创建一个程序计数器,每当类第一次被创建为对象时,将计数器设为1如果有新的引用指向该对象,计数器+1;失去一个引用,计数器—1当计数器变为0,该对象就可以被回收
1.4 内存泄漏和内存溢出当程序员创建对象的时候,GC就会开始监控对象,通过有向图的方式记录和管理堆中的所有对象从一个根节点GC ROOT开始,依次向下寻找对应的引用的节点,所寻找的路径成为引用链当一个对象没有任何引用链与GC链接的时候,就可以被回收了
内存泄漏
内存泄漏(memory leak):指应用程序在申请内存后,无法释放已经申请的内存空间。一次泄露可以忽略不计,但是多次内存泄漏会到此内存溢出out of memory。
如读取文件后需要关闭流、sql连接完毕后要进行释放、内部类的使用等
内存溢出
1.5 为什么重写equals()方法时必须要重写hashCode()方法内存溢出(out of memory):应用程序在申请内存的时候,没有足够的内存供其使用,导致程序停机
例如我们在项目中对于大批量数据的导入采用分批的方式进行
1.6 强引用、软引用、弱引用、虚引用hashCode()的作用是获取哈希码,也称为散列码;它实际上是返回一个int整数。这个哈希码的作用是确定该对象在哈希表中的索引位置。如果两个对象相等,则hashcode一定也是相同的;如果两个对象相等,对两个对象分别调用equals方法都返回true。如果两个对象有相同的hashcode值,它们也不一定是相等的;因此equals方法被覆盖过,则hashCode方法也必须被覆盖。hashCode()的默认行为是对堆上的对象产生独特值。如果没有重写hashCode(),则该class的两个对象无论如何都不会相等(即使这两个对象指向相同的数据).
强引用:最普遍的一种引用方式,只要强引用存在,则垃圾回收器就不会回收这个对象。软引用:用于描述还有用但非必须的对象,如果内存足够,不回收,如果内存不足,则回收。一般用于实现内存敏感的高速缓存,软引用可以和引用队列ReferenceQueue联合使用,如果软引用的对象被垃圾回收,JVM就会把这个软引用加入到与之关联的引用队列中弱引用:一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存
圾回收,JVM就会把这个软引用加入到与之关联的引用队列中弱引用:一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存虚引用:其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。虚引用主要用来跟踪对象被垃圾回收器回收的活动。虚引用必须和引用队列(ReferenceQueue)联合使用



