Java基础复习笔记对象状态引用种类垃圾回收形式Word格式文档下载.doc
- 文档编号:1452039
- 上传时间:2023-04-30
- 格式:DOC
- 页数:6
- 大小:41.50KB
Java基础复习笔记对象状态引用种类垃圾回收形式Word格式文档下载.doc
《Java基础复习笔记对象状态引用种类垃圾回收形式Word格式文档下载.doc》由会员分享,可在线阅读,更多相关《Java基础复习笔记对象状态引用种类垃圾回收形式Word格式文档下载.doc(6页珍藏版)》请在冰点文库上搜索。
之后垃圾回收器在调用该对象的finalize方法的时候,在方法体内也没有任何变量引用、指向这个对象,还对象就变为了不可达状态!
如果还有其他变量的指针指向了他,那么就是又回到了可达状态!
其实可恢复状态的走向关键就是看finalize方法的执行体了。
不可恢复状态:
不可恢复状态就是相当于对对像下了死刑报告了!
!
利用完了,该对象已经没有利用价值了,等着让垃圾回收器将该对象“和谐”了吧。
Stringstr=newString("
是素还真与谈无欲"
);
str变量指向了一个字符串对象,该对象指向了一个对象池中缓存的字符串值”是素还真与谈无欲”。
这个时候该对象是可达状态,因为确实有一个变量str在指向它。
str=newString("
不是谈无欲与素还真"
这个时候是str指向了另一个内存中的对象,该对象指向了对象池缓存中的一个字符串”不是谈无欲与素还真”。
也就是说之前的对象(就是指向”是素还真与谈无欲”的对象)此时已经没有其他任何实在的变量引用它了,在该对象的finalize执行完毕前,它是一个可恢复状态。
如果在后面的程序又有其他变量指向了该对象,那么该对象还是可达状态,如果直到执行完finalize方法后还没有切实的变量引用它,那就证明它真的没有任何利用价值了,垃圾回收器见到这样的对象就说了:
“来,该我工作了,老子和谐了你!
”。
4.Java的引用类型
对垃圾回收器来说判断一个对象是否可和谐的标准就在于该对象是否被某个对象引用了。
Java引用对象的类型是分为4种情况的。
强引用:
这是我们开发人员最常见的引用方式。
几乎95%的程序归根结底都是使用new一个对象,这个new就是变量————》强引用对像的方式。
强引用的对象就是按照对象状态去回收的,一个强引用的对象在不可恢复状态的时候,谁也救不了你,等着和谐吧。
软引用:
对于软引用的对象而言,当内存空间足够时,它不会被回收(当然了如果对象是不可恢复状态的话自然也不能免于被回收的命运)。
如果内存空间不够的时候就得回收这些被引用的对象了。
垃圾回收器会说:
“对不起,现在是困难时期,内存不够,房子不够住的,谁让你爸不是李刚呢(不是强引用)?
和谐了啊!
packagereference;
importjava.lang.ref.SoftReference;
classPerson{
Stringname;
intage;
@Override
publicStringtoString(){
returnname+"
:
"
+age;
}
}
publicclassSoftReferenceTest{
/**
*@paramargs
*@throwsInterruptedException
*/
publicstaticvoidmain(String[]args)throwsInterruptedException{
SoftReference<
Person>
[]stringArray=newSoftReference[100000];
Personperson=null;
for(inti=0;
i<
100000;
i++){
person=newPerson();
person.name="
叶小钗"
+i;
person.age=i;
stringArray[i]=newSoftReference<
(person);
}
System.gc();
System.runFinalization();
System.out.println(stringArray[1].get());
上面代码使用了软引用一个对象数组,当内存不够用时stringArray[1].get()的值是null,也就是说软引用释放了该内存区域的值,而stringArray[9999].get()的值不是null,证明软引用声明的连续区域从前往后释放。
也就是最先占用内存的最先释放,后占用内存的后释放。
弱引用:
如果说强引用的对象是李刚之子,那么弱引用我就比喻为早上卖煎饼的小商贩,而垃圾回收器这个时候我把它比喻为城管。
只要城管的一开车过来工作,你看那些小商贩,无论是不是正在给客户摊煎饼的,一个个都拉起了煎饼车,跑哦~~结论很简单,这个空间腾出来了!
弱引用比软引用的对象生命周期更短,它更加朝不保夕,一旦垃圾回收器运行工作起来,那么无论这个时候内存空间是否够用,弱引用对象一样被回收掉。
就像卖煎饼的商贩,你说他在那个地点做生意碍着精神文明和谐社会建设什么事情了?
TMD,城管一来就是不让你用这个地方,有折吗?
不说了,看代码吧。
Personperson=newPerson();
person.name="
秦假仙"
;
person.age=25;
WeakReference<
personWeakReference=newWeakReference<
(
person);
System.out.println(personWeakReference.get());
person=null;
一旦垃圾回收调用之后,那么弱引用get的是null;
这里要注意,一般弱引用不太会在应用程序中使用到,除非系统需求非常的极端,因为弱引用的对象是随着垃圾回收器的执行而消亡的,而垃圾回收器咱们程序员自身是不知道它什么时候执行的,也就是说弱引用对象生命周期即使是在内存空间非常大的环境下也都是不可控的。
一般弱引用还可以使用WeakHashMap来进行弱引用对象的使用。
虚引用:
这个笔者也没用过,所以摘录网上的资料写在这里
虚引用"
顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。
如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收。
虚引用主要用来跟踪对象被垃圾回收的活动。
虚引用与软引用和弱引用的一个区别在于:
虚引用必须和引用队列(ReferenceQueue)联合使用。
当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。
程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。
程序如果发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。
5.内存溢出
内存溢出经常在哪些场合下会发生呢?
实际上主要就是数组、集合、循环中对象的增、减、覆盖操作并没有及时对原来的变量断开指针的引用,导致了该指针引用还客观存在着,尤其咱们一般编程中99.99%都是用的强引用类型,那么垃圾回收器发现这些在内存中的对象还有变量指向它呢,他会认为这块内存区域不应该回收,而实际上在应用程序中此对象已经没什么用处了,而只是我们使用中并没有及时给它断开指针链接罢了。
这样内存越来越紧张,到最后连续运行了30天或者更长时间的系统估计也得内存溢出——OutOfMemoryError。
6.垃圾回收的机制
垃圾回收机制是JVM比较核心的东西了,至于原理实际上网上有很多资料在讲解
垃圾收集的目的在于清除不再使用的对象。
GC通过确定对象是否被活动对象引用来确定是否收集该对象。
GC首先要判断该对象是否是时候可以收集。
两种常用的方法是引用计数和对象引用遍历。
引用计数收集器
引用计数是垃圾收集器中的早期策略。
在这种方法中,堆中每个对象(不是引用)都有一个引用计数。
当一个对象被创建时,且将该对象分配给一个变量,该变量计数设置为1。
当任何其它变量被赋值为这个对象的引用时,计数加1(a=b,则b引用的对象+1),但当一个对象的某个引用超过了生命周期或者被设置为一个新值时,对象的引用计数减1。
任何引用计数为0的对象可以被当作垃圾收集。
当一个对象被垃圾收集时,它引用的任何对象计数减1。
优点:
引用计数收集器可以很快的执行,交织在程序运行中。
对程序不被长时间打断的实时环境比较有利。
缺点:
无法检测出循环引用。
如父对象有一个对子对象的引用,子对象反过来引用父对象。
这样,他们的引用计数永远不可能为0.
跟踪收集器
早期的JVM使用引用计数,现在大多数JVM采用对象引用遍历。
对象引用遍历从一组对象开始,沿着整个对象图上的每条链接,递归确定可到达(reachable)的对象。
如果某对象不能从这些根对象的一个(至少一个)到达,则将它作为垃圾收集。
在对象遍历阶段,GC必须记住哪些对象可以到达,以便删除不可到达的对象,这称为标记(marking)对象。
下一步,GC要删除不可到达的对象。
删除时,有些GC只是简单的扫描堆栈,删除未标记的未标记的对象,并释放它们的内存以生成新的对象,这叫做清除(sweeping)。
这种方法的问题在于内存会分成好多小段,而它们不足以用于新的对象,但是组合起来却很大。
因此,许多GC可以重新组织内存中的对象,并进行压缩(compact),形成可利用的空间。
为此,GC需要停止其他的活动活动。
这种方法意味着所有与应用程序相关的工作停止,只有GC运行。
结果,在响应期间增减了许多混杂请求。
另外,更复杂的GC不断增加或同时运行以减少或者清除应用程序的中断。
有的GC使用单线程完成这项工作,有的则采用多线程以增加效率。
一些常用的垃圾收集器
◆标记-清除收集器
这种收集器首先遍历对象图并标记可到达的对象,然后扫描堆栈以寻找未标记对象并释放它们的内存。
这种收集器一般使用单线程工作并停止其他操作。
并且,由于它只是清除了那些未标记的对象,而并没有对标记对象进行压缩,导致会产生大量内存碎片,从而浪费内存。
◆标记-压缩收集器
有时也叫标记-清除-压缩收集器,与标记-清除收集器有相同的标记阶段。
在第二阶段,则把标记对象复制到堆栈的新域中以便压缩堆栈。
这种收集器也停止其他操作。
复制收集器
这种收集器将堆栈分为两个域,常称为半空间。
每次仅使用一半的空间,JVM生成的新对象则放在另一半空间中。
GC运行时,它把可到达对象复制到另一半空间,从而压缩了堆栈。
这种方法适用于短生存期的对象,持续复制长生存期的对象则导致效率降低。
并且对于指定大小堆来说,需要两倍大小的内存,因为任何时候都只使用其中的一半。
增量收集器
增量收集器把堆栈分为多个域,每次仅从一个域收集垃圾,也可理解为把堆栈分成一小块一小块,每次仅对某一个块进行垃圾收集。
这会造成较小的应用程序中断时间,使得用户一般不能觉察到垃圾收集器正在工作。
分代收集器
复制收集器的缺点是:
每次收集时,所有的标记对象都要被拷贝,从而导致一些生命周期很长的对象被来回拷贝多次,消耗大量的时间。
而分代收集器则可解决这个问题,分代收集器把堆栈分为两个或多个域,用以存放不同寿命的对象。
JVM生成的新对象一般放在其中的某个域中。
过一段时间,继续存在的对象(非短命对象)将获得使用期并转入更长寿命的域中。
分代收集器对不同的域使用不同的算法以优化性能。
并行收集器
并行收集器使用某种传统的算法并使用多线程并行的执行它们的工作。
在多CPU机器上使用多线程技术可以显著的提高java应用程序的可扩展性。
7.JVM参数设置
堆设置
-Xms:
初始堆大小
-Xmx:
最大堆大小
-XX:
NewSize=n:
设置年轻代大小
NewRatio=n:
设置年轻代和年老代的比值.如:
为3,表示年轻代与年老代比值为1:
3,年轻代占整个年轻代年老代和的1/4
SurvivorRatio=n:
年轻代中Eden区与两个Survivor区的比值.注意Survivor区有两个.如:
3,表示Eden:
Survivor=3:
2,一个Survivor区占整个年轻代的1/5
MaxPermSize=n:
设置持久代大小
收集器设置
+UseSerialGC:
设置串行收集器
+UseParallelGC:
设置并行收集器
+UseParalledlOldGC:
设置并行年老代收集器
+UseConcMarkSweepGC:
设置并发收集器
垃圾回收统计信息
+PrintGC
+PrintGCDetails
+PrintGCTimeStamps
-Xloggc:
filename
并行收集器设置
ParallelGCThreads=n:
设置并行收集器收集时使用的CPU数.并行收集线程数.
MaxGCPauseMillis=n:
设置并行收集最大暂停时间
GCTimeRatio=n:
设置垃圾回收时间占程序运行时间的百分比.公式为1/(1+n)
并发收集器设置
+CMSIncrementalMode:
设置为增量模式.适用于单CPU情况.
设置并发收集器年轻代收集方式为并行收集时,使用的CPU数.并行收集线程数.
6/6
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Java 基础 复习 笔记 对象 状态 引用 种类 垃圾 回收 形式