网络

教育改变生活

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 1383|回复: 0
打印 上一主题 下一主题

Java虚拟机—— 垃圾回收(一)

[复制链接]

271

主题

284

帖子

1243

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1243

最佳新人活跃会员热心会员突出贡献优秀版主

跳转到指定楼层
楼主
发表于 2019-8-2 09:59:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
JVM垃圾回收简介
在JVM提供垃圾回收,将内存空间不在使用的对象进行回收,垃圾回收主要针对堆空间,垃圾回收操作需要消耗一定的资源和时间;

JVM对堆空间进行分区:年轻代、年老代、永久代;
对年轻代的垃圾回收:minor GC
对年轻代和老年代同时作用的GC称为:Full GC

Java中的四种引用

Java 的堆内存和 GC 线程
当我们在 Java 上 new 一个对象的时候,都要在 java heap(堆)上为该对象开辟一块内存,当该对象的引用出作用域失效的时候,那么该对象就会作为 GC 垃圾回收器回收的目标之一。

GC 垃圾回收器是由 JVM 专门的一个线程,叫做垃圾回收线程来实现的,该线程的优先级比较低,因此,如果有的对象不被引用了,GC 是不会及时的回收该对象使用的内存的,但是我们有一种方法,当 GC线程执行的时候,可以让它更快的知道该对象是否能被立即回收,那就是当该对象不再使用的时候,把该对象的引用及时置 null,这样就可以帮助 GC 及时判断该对象不再被使用了,可以立即回收了。

大家都知道,所有的 Java 类都继承自 Object 类,该类里面有一个方法,如下:

在 Java 自定义类里面可以重写 finalize 方法,当对象被 GC 回收之前,会先调用对象的 finalize 方法,释放相关的资源,然后在 GC 的下一个回收周期里面,再把该对象的内存回收掉。

Java 是否存在内存泄露
Java 代码虽然不用我们自己释放对象,而是靠 GC 来回收对象内存,但最起码我们要告诉 GC 这个对象我们不用了,这样 GC 才能在一次垃圾回收周期内回收该对象的资源;

我们应该尽量减少 static 成员对象的定义,由于 static 域的成员在方法区,其生命周期和 Java 进程的生命周期是相等的,而且该 static 成员对象又引用了其他的对象,导致在一个直接引用链或者间接引用链上的所有对象都无法被 GC 回收;
我们自定义一个集合的时候,如果从逻辑上集合的某个对象已经不需要使用了,应该立刻把该对象的引用置为 null,否则会使该对象无法回收,造成内存泄露;内存泄漏以及jmap命令的用法;
还有其他的 I/O 流打开了却未关闭,如 File 打开没有关闭,Socket 打开没有关闭,数据库 Connection,Statement,Resultset 等对象打开,使用完了却没有关闭等等,都会造成内存资源泄露的问题。
如何将对象识别为垃圾:

1、引用记数法
对对象添加引用的标识,每对对象增加一个引用,引用标识进行+1操作,减少一个引用,标识-1,当标识为0的时候,说明对象不存在引用可以被回收;
缺点:无法处理对象间相互引用的问题;

2、可达性分析

判断对象是否存活,将堆中对象想象成一棵树,从树根(GC root)开始遍历所有的对象,能到达的称为可用对象,不能到达的称之为垃圾;

GC root一定是可达的,主要有:

虚拟机栈中引用的对象一定是可达的;

本地方法栈中的JNI引用的对象;

方法区中静态属性引用的对象;

方法区中常量引用的对象;


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

WEB前端

QQ|手机版|小黑屋|金桨网|助学堂  咨询请联系站长。

GMT+8, 2024-12-22 22:25 , Processed in 0.032565 second(s), 23 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表