- 浏览: 238465 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
xchd:
分别在什么时候(情况下)用ThreadFactory、Exec ...
Executor线程池实例 -
mikey_5:
是不是没有写完啊
Executor线程池实例 -
xinyao:
楼主,你好,请问能给我发个源码吗,我要在一个页面能实时看到下载 ...
Android学习系列(19)--App离线下载 -
sdtzkj:
...
jasperReport 帮助文档 api -
shero_ys:
public class VrowsePicActivity ...
android handler 实现三步曲
Java内存泄漏是每个Java程序员都会遇到的问题,程序在本地运行一切正常,可是布署到远端就会出现内存无限制的增长,最后系统瘫痪,那么如何最快最好的检测程序的稳定性,防止系统崩盘,作者用自已的亲身经历与各位网友分享解决这些问题的办法。 作为Internet最流行的编程语言之一,Java现正非常流行。我们的网络应用程序就主要采用Java语言开发,大体上分为客户端、服务器和数据库三个层次。在进入测试过程中,我们发现有一个程序模块系统内存和CPU资源消耗急剧增加,持续增长到出现java.lang.OutOfMemoryError为止。经过分析Java内存泄漏是破坏系统的主要因素。这里与大家分享我们在开发过程中遇到的Java内存泄漏的检测和处理解决过程. 一. Java是如何管理内存 为了判断Java中是否有内存泄露,我们首先必须了解Java是如何管理内存的。Java的内存管理就是对象的分配和释放问题。在Java中,内存的分配是由程序完成的,而内存的释放是由垃圾收集器(Garbage Collection,GC)完成的,程序员不需要通过调用函数来释放内存,但它只能回收无用并且不再被其它对象引用的那些对象所占用的空间。 Java的内存垃圾回收机制是从程序的主要运行对象开始检查引用链,当遍历一遍后发现没有被引用的孤立对象就作为垃圾回收。GC为了能够正确释放对象,必须监控每一个对象的运行状态,包括对象的申请、引用、被引用、赋值等,GC都需要进行监控。监视对象状态是为了更加准确地、及时地释放对象,而释放对象的根本原则就是该对象不再被引用。 在Java中,这些无用的对象都由GC负责回收,因此程序员不需要考虑这部分的内存泄露。虽然,我们有几个函数可以访问GC,例如运行GC的函数System.gc(),但是根据Java语言规范定义,该函数不保证JVM的垃圾收集器一定会执行。因为不同的JVM实现者可能使用不同的算法管理GC。通常GC的线程的优先级别较低。JVM调用GC的策略也有很多种,有的是内存使用到达一定程度时,GC才开始工作,也有定时执行的,有的是平缓执行GC,有的是中断式执行GC。但通常来说,我们不需要关心这些。 二. 什么是Java中的内存泄露 导致内存泄漏主要的原因是,先前申请了内存空间而忘记了释放。如果程序中存在对无用对象的引用,那么这些对象就会驻留内存,消耗内存,因为无法让垃圾回收器GC验证这些对象是否不再需要。如果存在对象的引用,这个对象就被定义为"有效的活动",同时不会被释放。要确定对象所占内存将被回收,我们就要务必确认该对象不再会被使用。典型的做法就是把对象数据成员设为null或者从集合中移除该对象。但当局部变量不需要时,不需明显的设为null,因为一个方法执行完毕时,这些引用会自动被清理。 在Java中,内存泄漏就是存在一些被分配的对象,这些对象有下面两个特点,首先,这些对象是有被引用的,即在有向树形图中,存在树枝通路可以与其相连;其次,这些对象是无用的,即程序以后不会再使用这些对象。如果对象满足这两个条件,这些对象就可以判定为Java中的内存泄漏,这些对象不会被GC所回收,然而它却占用内存。 这里引用一个常看到的例子,在下面的代码中,循环申请Object对象,并将所申请的对象放入一个Vector中,如果仅仅释放对象本身,但因为Vector仍然引用该对象,所以这个对象对GC来说是不可回收的。因此,如果对象加入到Vector后,还必须从Vector中删除,最简单的方法就是将Vector对象设置为null。 Vector v = new Vector(10);for (int i = 1; i < 100; i++)......{ Object o = new Object(); v.add(o); o = null;}//此时,所有的Object对象都没有被释放,因为变量v引用这些对象。 Logger类有一个类型为HashMap的静态变量temp,每次在执行log(message)的时候,都首先将message的值写入temp中(以当前线程+当前时间为键),在退出之前再从temp中将以当前线程和当前时间为键的条目删除。注意,这里当前时间是不断变化的,所以log在退出之前执行删除条目的操作并不能删除执行之初写入的条目。这样,任何一个作为参数传给log的字符串最终由于被Logger的静态变量temp引用,而无法得到回收,这种对象保持就是我们所说的Java内存泄漏。总的来说,内存管理中的内存泄漏产生的主要原因:保留下来却永远不再使用的对象引用。 三. 几种典型的内存泄漏 我们知道了在Java中确实会存在内存泄漏,那么就让我们看一看几种典型的泄漏,并找出他们发生的原因和解决方法。 3.1 全局集合 通常有很多不同的解决形式,其中最常用的是一种周期运行的清除作业。这个作业会验证仓库中的数据然后清除一切不需要的数据。 另一种管理储存库的方法是使用反向链接(referrer)计数。然后集合负责统计集合中每个入口的反向链接的数目。这要求反向链接告诉集合何时会退出入口。当反向链接数目为零时,该元素就可以从集合中移除了。 常用的解决途径是使用java.lang.ref.SoftReference类坚持将对象放入缓存。这个方法可以保证当虚拟机用完内存或者需要更多堆的时候,可以释放这些对象的引用。 3.3 类装载器 四. 如何检测和处理内存泄漏 第一个步骤在代码走查的工作中,可以安排对系统业务和开发语言工具比较熟悉的开发人员对应用的代码进行了交叉走查,尽量找出代码中存在的数据库连接声明和结果集未关闭、代码冗余等故障代码。 第二个步骤就是检测Java的内存泄漏。在这里我们通常使用一些工具来检查Java程序的内存泄漏问题。市场上已有几种专业检查Java内存泄漏的工具,它们的基本工作原理大同小异,都是通过监测Java程序运行时,所有对象的申请、释放等动作,将内存管理的所有信息进行统计、分析、可视化。开发人员将根据这些信息判断程序是否有内存泄漏问题。这些工具包括Optimizeit Profiler,JProbe Profiler,JinSight , Rational 公司的Purify等。 4.1检测内存泄漏的存在 一般说来,一个正常的系统在其运行稳定后其内存的占用量是基本稳定的,不应该是无限制的增长的。同样,对任何一个类的对象的使用个数也有一个相对稳定的上限,不应该是持续增长的。根据这样的基本假设,我们持续地观察系统运行时使用的内存的大小和各实例的个数,如果内存的大小持续地增长,则说明系统存在内存泄漏,如果特定类的实例对象个数随时间而增长(就是所谓的“增长率”),则说明这个类的实例可能存在泄漏情况。 另一方面通常发生内存泄漏的第一个迹象是:在应用程序中出现了OutOfMemoryError。在这种情况下,需要使用一些开销较低的工具来监控和查找内存泄漏。虽然OutOfMemoryError也有可能应用程序确实正在使用这么多的内存;对于这种情况则可以增加JVM可用的堆的数量,或者对应用程序进行某种更改,使它使用较少的内存。 但是,在许多情况下,OutOfMemoryError都是内存泄漏的信号。一种查明方法是不间断地监控GC的活动,确定内存使用量是否随着时间增加。如果确实如此,就可能发生了内存泄漏。 4.2处理内存泄漏的方法 Optimizeit是Borland公司的产品,主要用于协助对软件系统进行代码优化和故障诊断,其中的Optimizeit Profiler主要用于内存泄漏的分析。Profiler的堆视图就是用来观察系统运行使用的内存大小和各个类的实例分配的个数的。 首先,Profiler会进行趋势分析,找出是哪个类的对象在泄漏。系统运行长时间后可以得到四个内存快照。对这四个内存快照进行综合分析,如果每一次快照的内存使用都比上一次有增长,可以认定系统存在内存泄漏,找出在四个快照中实例个数都保持增长的类,这些类可以初步被认定为存在泄漏。通过数据收集和初步分析,可以得出初步结论:系统是否存在内存泄漏和哪些对象存在泄漏(被泄漏)。 接下来,看看有哪些其他的类与泄漏的类的对象相关联。前面已经谈到Java中的内存泄漏就是无用的对象保持,简单地说就是因为编码的错误导致了一条本来不应该存在的引用链的存在(从而导致了被引用的对象无法释放),因此内存泄漏分析的任务就是找出这条多余的引用链,并找到其形成的原因。查看对象分配到哪里是很有用的。同时只知道它们如何与其他对象相关联(即哪些对象引用了它们)是不够的,关于它们在何处创建的信息也很有用。 最后,进一步研究单个对象,看看它们是如何互相关联的。借助于Profiler工具,应用程序中的代码可以在分配时进行动态添加,以创建堆栈跟踪。也有可以对系统中所有对象分配进行动态的堆栈跟踪。这些堆栈跟踪可以在工具中进行累积和分析。对每个被泄漏的实例对象,必然存在一条从某个牵引对象出发到达该对象的引用链。处于堆栈空间的牵引对象在被从栈中弹出后就失去其牵引的能力,变为非牵引对象。因此,在长时间的运行后,被泄露的对象基本上都是被作为类的静态变量的牵引对象牵引。 ************************************************************************************************************ |
发表评论
-
Android JNI简单实例(android 调用C/C++代码)
2011-05-25 11:19 6261Android的jni实例 android 的应用程序( ... -
设计模式之Factory
2011-02-12 10:14 810工厂模式定义:提供创建对象的接口. 为何使用?工厂模式是我们 ... -
svn配置方法
2011-01-06 15:37 884Install Subclipse in Eclipse 3. ... -
Java面向对象
2010-12-27 13:15 809编程模型 所有计算 ... -
用java原生api写解压缩
2010-12-06 09:27 787package com.unis.io; impo ... -
java 多线程详解
2010-11-26 15:42 1129目录: Java线程:概念与原理... 3 Java ... -
Java 多线程总结
2010-11-11 11:04 949最近想将java基础的一些 ... -
项目部署
2010-06-30 09:30 772是 -
java 读取文件
2010-06-17 13:53 1340java 读取 txt文件 ... -
生成hibernate配置文件
2010-06-13 15:32 618项目添加hibernate配置文件: 1. 首先 ... -
使用JDOM来生成XML文档
2010-05-17 17:11 1538下面介绍使用Eclipse来加载JDOM的jar包,同时利用J ... -
日期类型之间转换
2010-05-06 12:08 958public static Timestamp parseT ... -
JSTL详解--EL表达式
2010-03-25 11:03 1118在 JSP 页面中,使用标签库代替传统的 Java 片段语 ... -
JSTL 学习、应用记录
2010-03-24 17:25 1001JSTL 学习、应用记录 原来一直没有看过,我说过我是新手, ... -
Struts2+Spring整合
2010-03-08 16:01 1224Struts2和Spring整合,创建一个OA工程 1、整合s ... -
S2SH整合配置
2010-03-08 10:29 1267配置方法1: ********************* ... -
hibernate中lazy的使用
2010-03-08 10:25 808hibernate中lazy的使用 lazy,延迟 ... -
Java static final
2010-03-05 13:54 1676Java关键字final、static使用总结 一、 ... -
Java 反射机制
2010-03-05 09:56 800JAVA反射机制 JAV ... -
Java 工厂模式
2010-03-02 10:59 8116 推荐 一、引子话说十年 ...
相关推荐
因此,了解Java内存泄漏的成因、检测方法以及解决方案对于保证应用的高效稳定运行至关重要。 #### 2. Java内存回收机制 Java的内存管理主要集中在堆(Heap)区域,其中对象的创建通常是通过`new`关键字或反射方式...
4. Native内存泄漏:Java应用可能使用JNI(Java Native Interface)与C/C++代码交互,若C/C++部分存在内存泄漏,也会间接导致Java内存泄漏。 解决内存泄漏的方法主要包括: 1. 使用工具监控:通过工具如VisualVM、...
### Java内存泄漏解决方案详解 #### 一、Java内存泄漏概述 在Java开发过程中,经常会遇到内存泄漏的问题,尤其是在长时间运行的应用程序中更为常见。本文将详细介绍如何解决Java内存泄漏问题,帮助开发者更好地...
Java 内存泄露 解决方案 outofmemoryException 从实践获取真理
Java 内存泄漏是开发过程中常见且棘手的问题,它可能导致程序性能急剧下降,最终甚至导致系统崩溃。本文将深入探讨 Java 内存管理机制、内存泄漏的定义以及如何检测和预防这类问题。 首先,Java 的内存管理主要依赖...
在Java编程中,内存泄漏是一个严重的问题,尤其对于长时间运行的应用程序,它可能...通过细心的代码审查、合理的对象管理和利用工具进行监控,我们可以有效地避免和解决Java内存泄漏问题,从而确保应用的稳定性和性能。
总结来说,Java内存泄漏的预防和解决需要深入理解GC的工作原理,合理管理对象引用,特别是在全局数据结构、缓存和类加载器中。此外,利用合适的工具进行监控和分析,可以更有效地定位和修复内存泄漏问题,从而提升...
4. "java内存泄露专题研究和应用_石麟.docx"可能提供了更深入的研究和实际案例,包括如何识别特定类型的内存泄漏,以及针对不同场景下的解决方案。而"ha450.jar"可能是一个示例应用或者工具,用于演示内存泄漏问题...
这份13页的PDF文档,"java内存泄露定位与分析",很显然是针对Java开发者深入理解内存管理的重要资源。我们将探讨其中可能涵盖的关键知识点。 首先,内存泄露是指程序在申请内存后,无法释放已不再使用的内存空间。...
### Java内存泄漏原因分析大全 #### 摘要 本文旨在深入探讨Java内存泄漏的各种成因,以及如何预防这些问题的发生。尽管Java虚拟机(JVM)及其内置的垃圾回收机制在很大程度上减轻了开发者手动管理内存的压力,但在...
本文旨在深入探讨Java中的内存泄露问题及其解决方案。 #### Java的内存管理:GARBAGE COLLECTION详解 垃圾收集器(GC)在Java中扮演着至关重要的角色,它负责自动回收不再使用的对象所占用的内存。在Java中,所有...
在本文中,我们将详细介绍Java内存泄漏的定义、原因、排查方法、解决方案,并提供一个简单的Java代码示例来演示内存泄漏的可能情况。 一、Java内存泄漏的定义和原因 Java内存泄漏是指在Java程序中存在一些不再使用...
本文将基于一个真实的案例,深入探讨Java内存溢出的原因分析、解决方案以及常用的检查方法和工具。 #### 二、Java内存管理基础知识 在理解内存泄露和溢出之前,我们需要先了解Java虚拟机(JVM)的基本内存结构及其...
本文将深入探讨Java内存溢出的不同类型及其解决方案。 1. **内存溢出类型** - **1.1. java.lang.OutOfMemoryError: PermGen space** PermGen空间是JVM用于存储类元数据和常量池的部分,不会被垃圾收集器自动...
### 深入理解Java中的内存泄漏解决方案 #### 内存泄漏的概念与...综上所述,Java内存泄漏虽然是一种常见的问题,但通过合理的代码设计、正确的集合类使用以及利用工具进行监控和调试,可以有效地避免和解决这类问题。
2. **MAT (Memory Analyzer Tool)**:Eclipse 提供的专门用于分析Java堆内存的工具,它能帮助开发者定位内存泄漏的具体对象和引用链。MAT的 Leak Suspects 报告和 Dominator Tree 功能特别适用于发现潜在的内存泄露...
解决方案是优化代码,减少递归或调整栈的大小(通过-Xss设置)。 3. **方法区/永久代溢出**: 方法区用于存储类信息、常量、静态变量等。JDK8之前,这部分内存被称为永久代,容易因类信息过多而溢出。JDK9之后,这...