Java提高篇—— 简单介绍Java 的内存泄漏

news/2024/7/20 12:56:36 标签: java, 内存管理

  java最明显的一个优势就是它的内存管理机制。你只需简单创建对象,java的垃圾回收机制负责分配和释放内存。然而情况并不像想像的那么简单,因为在Java应用中经常发生内存泄漏。

本教程演示了什么是内存泄漏,为什么会发生内存泄漏以及如何预防内存泄漏。

什么是内存泄漏?

定义:如果对象在应用中不再被使用,但由于它们在其他地方被引用,垃圾回收却不能移除它们(这样就造成了很多内存不能释放,从而导致内存溢出的现象。译注)。

要理解这一定义,我们需要理解内存中对象的状态。下图说明了那些是未使用,那些是未引用。

where-is-memory-leak

从图中可以看到被引用对象和未引用对象(的范围)。未引用对象可以被垃圾回收机制回收,而被引用对象不能被垃圾回收机制回收。未引用对象当然是没有使用的,因为没有其他对象引用了它。然而未使用对象并不都是未引用的。某些未使用的对象仍然被其他地方引用!这就是内存泄漏起因。

为什么会发生内存泄漏?

让我们来下面的这个例子,看看为什么会发生内存泄漏。在如下例子中,A对象引用了B对象。A的生命周期(t1-t4)比B的生命周期(t2-t3)要长的多,当B不再在应用中被使用,A仍然持有对B的引用。这样一来,垃圾回收机制不能从内存中移除B。这很有可能导致内存溢出问题,因为如果其他很多对象像A一样,那么内存中将会有很多不能被回收的对象,这将消耗大量内存空间。

也有可能的情况是B持有了大量对其他对象的引用。这些被B引用的对象同样不会被回收掉。所有这些未使用的对象将会消耗宝贵的内存空间。 

如何预防内存泄漏?

如下是一些预防内存泄漏的快速技巧:

1、留意集合类,比如HashMap,ArrayList等等,因为他们是内存泄漏经常发生的地方。当它们被声明为静态对象时,他们的生命周期就和应用的生命周期一样长。

2、留意事件监听器和回调。如果一个类注册了监听器,但当该类不再被使用后没有注销监听器,可能会发生内存泄漏。

3、“如果一个类管理自己的内存,程序员应该警惕内存泄漏。”[1],很多时候对象中的指向其他对象成员变量需要设置成null(才能被回收)。

一个小测验:为什么JDK6中的substring()方法会引发内存泄漏?

要回答这个问题,你可能需要查看JDK6和7中substring()的源码。

参考文献:
1. Bloch, Joshua. Effective java. Addison-Wesley Professional, 2008.
2. IBM Developer Work. http://www.ibm.com/developerworks/library/j-leaks/

转载于:https://www.cnblogs.com/Qian123/p/5706440.html


http://www.niftyadmin.cn/n/997452.html

相关文章

C++ HttpWebRequest发送POST请求,参数以json格式传递

string PostUrl "URL";JObject patientinfo new JObject();patientinfo["name"] "TOM";patientinfo["age"] 12;string sendData JsonConvert.SerializeObject(patientinfo);//eg: 发送Url需要的格式:sendData{"…

PHP 自定义session储存 MEMCACHE 方式类   高洛峰 细说PHP

自定义session储存 MEMCACHE 方式类在php.ini配置文件中更改设置 (Registered_save_handlers 有三种方式 files user memcache)session.save_handler user 表示用户自定义session类<?php /** 自定义session储存memcache方式的类* */class MemSession{ public static …

创建kafkatopic和productor

cd 到kafka 目录下 创建topic create topicbin/kafka-topics.sh --zookeeper spark1:2181,spark2:2181,spark3:2181 --topic WordCount --replication-factor 1 --partitions 1 --create 创建生产断 bin/kafka-console-producer.sh --broker-list spark1:9092,spark2:9092,spar…

Python根据关键词在360、百度、bing搜索下载图片

DownloaderImage 项目地址:https://github.com/404SpiderMan/DownloadImage&#xff08;求star&#xff09; 1. 简介 输入一组关键词&#xff0c;指定所需图片个数&#xff0c;在常见搜索引擎中检索&#xff0c;记录图片url地址&#xff0c;并将图片保存在指定目录下。 百度…

maven项目修改java编译版本的方式

背景 使用 maven 3.x 安装到本地后&#xff0c;创建的项目一般都是基于JDK1.5版本。而目前大多数的项目已经升级到1.6或以上&#xff0c;尤其是Servlet3.0 已经要求Java6或以上版本的环境&#xff0c;往往需要改动。 解决方案 方案一&#xff1a;全局设置 在${MAVEN_HOME}/conf…

mysql 查询获取排名的方法

为什么80%的码农都做不了架构师&#xff1f;>>> 需求&#xff1a;获取勤奋指数 登录天数/开通天数 解决方法&#xff1a; select * from ( select scores.score,rank:rank1 as rank,scores.user_id from (SELECTifnull(round(login_days/datediff(2016-12-31,open…

linux中的优先搜索树的实现--prio_tree【转】

转自&#xff1a;http://blog.csdn.net/bailyzheng/article/details/8041943 linux中的优先搜索树的实现--prio_tree prio_tree在linux内核中被应用于反向内存映射&#xff0c;prio-tree是一棵查找树&#xff0c;它查找的是一个区间&#xff0c;为何将之组织成tree是一个数学问…

PC微信获取朋友圈数据api接口

采用http通信方便调用 获取首页数据: http://10.222.6.70:6688/get?page-1翻页&#xff1a; http://10.222.6.70:6688/get?page13666459078131650946数据包括发布时间、username、wxid、点赞等数据 交流体验获取请联系 console.log("wx:spiderskill") 欢迎关注…