`
yajie
  • 浏览: 206350 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

Java的最优化内存管理

阅读更多
       1、Java的内存管理就是对象的分配和释放问题。
    在Java中,程序员需要通过关键字new为每个对象申请内存空间 (基本类型除外),所有的对象都在堆 (Heap)中分配空间。
    对象的释放是由GC决定和执行的。
    在Java中,内存的分配是由程序完成的,而内存的释放是有GC完成的,这种收支两条线的方法简化了程序员的工作。但也加重了JVM的工作。这也是Java程序运行速度较慢的原因之一。

    GC释放空间方法:
    监控每一个对象的运行状态,包括对象的申请、引用、被引用、赋值等。当该对象不再被引用时,释放对象。


    2、内存管理结构
    Java使用有向图的方式进行内存管理,对于程序的每一个时刻,我们都有一个有向图表示JVM的内存分配情况。

    将对象考虑为有向图的顶点,将引用关系考虑为图的有向边,有向边从引用者指向被引对象。另外,每个线程对象可以作为一个图的起始顶点,例如大多程序从 main进程开始执行,那么该图就是以main进程顶点开始的一棵根树。在这个有向图中,根顶点可达的对象都是有效对象,GC将不回收这些对象。如果某个 对象 (连通子图)与这个根顶点不可达(注意,该图为有向图),那么我们认为这个(这些)对象不再被引用,可以被GC回收。

    3、使用有向图方式管理内存的优缺点
    Java使用有向图的方式进行内存管理,可以消除引用循环的问题,例如有三个对象,相互引用,只要它们和根进程不可达的,那么GC也是可以回收它们的。
    这种方式的优点是管理内存的精度很高,但是效率较低。

另外一种常用的内存管理技术是使用计数器,例如COM模型采用计数器方式管理构件,它与有向图相比,精度行低(很难处理循环引用的问题),但执行效率很高。

★  Java的内存泄露
    Java虽然由GC来回收内存,但也是存在泄露问题的,只是比C++小一点。

    1、与C++的比较
    c++所有对象的分配和回收都需要由用户来管理。即需要管理点,也需要管理边。若存在不可达的点,无法在回收分配给那个点的内存,导致内存泄露。存在无用的对象引用,自然也会导致内存泄露。
    Java由GC来管理内存回收,GC将回收不可达的对象占用的内存空间。所以,Java需要考虑的内存泄露问题主要是那些被引用但无用的对象——即指要管理边就可以。被引用但无用的对象,程序引用了该对象,但后续不会再使用它。它占用的内存空间就浪费了。
        如果存在对象的引用,这个对象就被定义为“活动的”,同时不会被释放。

    2、Java内存泄露处理
    处理Java的内存泄露问题:确认该对象不再会被使用。
    典型的做法——
        把对象数据成员设为null
        从集合中移除该对象
    注意,当局部变量不需要时,不需明显的设为null,因为一个方法执行完毕时,这些引用会自动被清理。

例子:

  1. <span style= "font-size:16px;" >List myList= new  ArrayList();  
  2. for  ( int  i= 1 ;i< 100 ; i++)  
  3. {  
  4. Object o=new  Object();  
  5. myList.add(o);  
  6. o=null ;  
  7. }  
  8. //此时,所有的Object对象都没有被释放,因为变量myList引用这些对象。   
  9. </span>  

 当myList后来不再用到,将之设为null,释放所有它引用的对象。之后GC便会回收这些对象占用的内存。

★  对GC操作
    对GC的操作并不一定能达到管理内存的效果。

    GC对于程序员来说基本是透明的,不可见的。我们只有几个函数可以访问GC,例如运行GC的函数System.gc(),System.。
    但是根据Java语言规范定义, System.gc()函数不保证JVM的垃圾收集器一定会执行。因为,不同的JVM实现者可能使用不同的算法管理GC。通常,GC的线程的优先级别较低。


    JVM调用GC的策略有很多种,有的是内存使用到达一定程度时,GC才开始工作,也有定时执行的,有的是平缓执行GC,有的是中断式执行GC。但通常来 说,我们不需要关心这些。除非在一些特定的场合,GC的执行影响应用程序的性能,例如对于基于Web的实时系统,如网络游戏等,用户不希望GC突然中断应 用程序执行而进行垃圾回收,那么我们需要调整GC的参数,让GC能够通过平缓的方式释放内存,例如将垃圾回收分解为一系列的小步骤执行,Sun提供的 HotSpot JVM就支持这一特性。

★  内存泄露检测
    市场上已有几种专业检查Java内存泄漏的工具,它们的基本工作原理大同小异,都是通过监测Java程序运行时,所有对象的申请、释放等动作,将内存管理 的所有信息进行统计、分析、可视化。开发人员将根据这些信息判断程序是否有内存泄漏问题。这些工具包括Optimizeit Profiler,JProbe Profiler,JinSight , Rational 公司的Purify等。

    在运行过程中,我们可以随时观察内存的使用情况,通过这种方式,我们可以很快找到那些长期不被释放,并且不再使用的对象。我们通过检查这些对象的生存周期,确认其是否为内存泄露。

★  软引用
    特点:只有当内存不够的时候才回收这类内存,同时又保证在Java抛出OutOfMemory异常之前,被设置为null。
          保证最大限度的使用内存而不引起OutOfMemory异常。
          在某些时候对软引用的使用会降低应用的运行效率与性能,例如:应用软引用的对象的初始化过程较为耗时,或者对象的状态在程序的运行过程中发生了变化,都会给重新创建对象与初始化对象带来不同程度的麻烦。

    用途:
    可以用于实现一些常用资源的缓存,实现Cache的功能
    处理一些占用内存大而且声明周期较长,但使用并不频繁的对象时应尽量应用该技术

★  java程序设计中有关内存管理的经验

1.最基本的建议是尽早释放无用对象的引用。如:

  1. <span style= "font-size:16px;" >...  
  2. A a = new  A();  
  3. //应用a对象   
  4. a = null //当使用对象a之后主动将其设置为空   
  5. ….</span>  



注:如果a 是方法的返回值,不要做这样的处理,否则你从该方法中得到的返回值永远为空,而且这种错误不易被发现、排除

2.尽量少用finalize函数。它会加大GC的工作量。
3.如果需要使用经常用到的图片,可以使用soft应用类型。它尽可能把图片保存在内存中
4.注意集合数据类型,包括数组、树、图、链表等数据结构,这些数据结构对GC来说,回收更为复杂。
5.尽量避免在类的默认构造器中创建、初始化大量的对象,防止在调用其自类的构造器时造成不必要的内存资源浪费
6.尽量避免强制系统做垃圾内存的回收,增长系统做垃圾回收的最终时间
7.尽量避免显式申请数组空间
8.尽量做远程方法调用类应用开发时使用瞬间值变量,除非远程调用端需要获取该瞬间值变量的值。
9.尽量在合适的场景下使用对象池技术以提高系统性能。

3
2
分享到:
评论

相关推荐

    java内存管理(堆、栈、方法区)

    因此,了解并掌握Java的内存管理是我们必须要做的是事,也只有这样才能写出更好的程序,更好地优化程序的性能。Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干不同的数据区域,这些区域都有各自的...

    最详细的java内存讲解

    JVM的垃圾回收机制详解和调优; 深入Java核心 Java内存分配原理精讲; 详细介绍Java的内存管理与内存泄露;

    java内存泄漏

    Java语言对内存管理做了自己的优化,这就是垃圾回收机制。Java的几乎所有内存对象都是在堆内存上分配(基本数据类型除外),然后由GC(garbage collection)负责自动回收不再使用的内存。  上面是Java内存管理机制...

    操作系统(内存管理)

    让我们来了解可用于内存管理的不同方法,它们的好处与不足,以及它们最适用的情形。 回页首 C 风格的内存分配程序 C 编程语言提供了两个函数来满足我们的三个需求: malloc:该函数分配给定的字节...

    精品:java虚拟机分析与优化PPT

    我们将分析它是如何进行垃圾回收,内存管理,堆压缩,以及其他高级特性。我们还将研究如何配置JVM使得性能得以最优化。演讲者将列出对于IBM和SUN JVM在1.4.2以及1.5版本上对WebSphere有用的一组调优参数。如果您对...

    java源码包---java 源码 大量 实例

     Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。 递归遍历矩阵 1个目标文件,简单! 多人聊天室 3...

    JAVA上百实例源码以及开源项目

     Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。 递归遍历矩阵 1个目标文件,简单! 多人聊天室 3...

    java源码包4

     Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。 递归遍历矩阵 1个目标文件,简单! 多人聊天室 ...

    java源码包3

     Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。 递归遍历矩阵 1个目标文件,简单! 多人聊天室 ...

    JAVA上百实例源码以及开源项目源代码

     Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。 递归遍历矩阵 1个目标文件,简单! 多人聊天室 3...

    java源码包2

     Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。 递归遍历矩阵 1个目标文件,简单! 多人聊天室 ...

    Java入门教程.docx

    Java程序易于编写,而且有内置垃圾收集,不必考虑内存管理; Java虚拟机拥有工业级的稳定性和高度优化的性能,且经过了长时期的考验; Java拥有最广泛的开源社区支持,各种高质量组件随时可用。 Java语言常年霸占...

    Java + 基础练习 + 项目

    Java程序易于编写,而且有内置垃圾收集,不必考虑内存管理; Java虚拟机拥有工业级的稳定性和高度优化的性能,且经过了长时期的考验; Java拥有最广泛的开源社区支持,各种高质量组件随时可用。 Java语言常年霸占着...

    Java项目:宠物领养寄养商城系统(java+Springboot+HTML+bootstrap+mysql)

    1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。 2.IDE环境:IDEA,Eclipse,Myeclipse都可以。推荐IDEA; 3.tomcat环境:Tomcat 7.x,8.x,9.x版本均可 4.硬件环境:windows 7/8/10 1...

    Java + 数组 + 初始化

    Java程序易于编写,而且有内置垃圾收集,不必考虑内存管理; Java虚拟机拥有工业级的稳定性和高度优化的性能,且经过了长时期的考验; Java拥有最广泛的开源社区支持,各种高质量组件随时可用。 Java语言常年霸占着...

    Java VM Heap 堆分析(节选)

    JVM堆分析,Java VM堆分析(节选)。 JProbe 是目前最好的Java... 本文档不但介绍了JProbe的在解决内存问题方面的功能和使用,同时还介绍了必要的Java内存管理的背景知识,深入浅出,是提高Java代码质量的必备资料。

    Java + 集合 + TreeSet +定制排序

    Java程序易于编写,而且有内置垃圾收集,不必考虑内存管理; Java虚拟机拥有工业级的稳定性和高度优化的性能,且经过了长时期的考验; Java拥有最广泛的开源社区支持,各种高质量组件随时可用。 Java语言常年霸占着...

    成百上千个Java 源码DEMO 4(1-4是独立压缩包)

    2个目标文件 摘要:Java源码,文件操作,TCP,服务器 Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。...

    史上最全经典排序算法总结(Java实现).zip

    安全:Java提供了丰富的安全特性,如禁止指针运算、自动内存管理和异常处理机制,以减少程序错误和恶意攻击的可能性。 可移植性:Java字节码可以在所有安装了JVM的设备上执行,从服务器到嵌入式系统,再到移动...

Global site tag (gtag.js) - Google Analytics