`
lvwenwen
  • 浏览: 930503 次
  • 性别: Icon_minigender_1
  • 来自: 魔都
社区版块
存档分类
最新评论

深入Java虚拟机之内存优化

    博客分类:
  • Jvm
阅读更多

前面一篇文章介绍了Java虚拟机的体系结构和内存模型,既然提到内存,就不得不说到内存泄露。众所周知,Java是从C++的基础上发展而来的,而C++程序的很大的一个问题就是内存泄露难以解决,尽管Java的JVM有一套自己的垃圾回收机制来回收内存,在许多情况下并不需要java程序开发人员操太多的心,但也是存在泄露问题的,只是比C++小一点。比如说,程序中存在被引用但无用的对象:程序引用了该对象,但后续不会或者不能再使用它,那么它占用的内存空间就浪费了。

 

我们先来看看GC是如何工作的:监控每一个对象的运行状态,包括对象的申请、引用、被引用、赋值等,当该对象不再被引用时,释放对象(GC本文的重点,不做过多阐述)。很多Java程序员过分依赖GC,但问题的关键是无论JVM的垃圾回收机制做得多好,内存总归是有限的资源,因此就算GC会为我们完成了大部分的垃圾回收,但适当地注意编码过程中的内存优化还是很必要的。这样可以有效的减少GC次数,同时提升内存利用率,最大限度地提高程序的效率。

 

总体而言,Java虚拟机的内存优化应从两方面着手:Java虚拟机和Java应用程序。前者指根据应用程序的设计通过虚拟机参数控制虚拟机逻辑内存分区的大小以使虚拟机的内存与程序对内存的需求相得益彰;后者指优化程序算法,降低GC负担,提高GC回收成功率。

 

通过参数优化虚拟机内存的参数如下所示:
-Xms 
初始Heap大小

-Xmx 
java heap最大值 

-Xmn 
young generation的heap大小

-Xss 
每个线程的Stack大小

上面是三个比较常用的参数,还有一些:
-XX:MinHeapFreeRatio=40
Minimum percentage of heap free after GC to avoid expansion.
 
-XX:MaxHeapFreeRatio=70
Maximum percentage of heap free after GC to avoid shrinking.
 
-XX:NewRatio=2
Ratio of new/old generation sizes. [Sparc -client:8; x86 -server:8; x86 -client:12.]-client:8 (1.3.1+), x86:12]
 
-XX:NewSize=2.125m
Default size of new generation (in bytes) [5.0 and newer: 64 bit VMs are scaled 30% larger; x86:1m; x86, 5.0 and older: 640k]
 
-XX:MaxNewSize=
Maximum size of new generation (in bytes). Since 1.4, MaxNewSize is computed as a function of NewRatio.
 
-XX:SurvivorRatio=25
Ratio of eden/survivor space size [Solaris amd64: 6; Sparc in 1.3.1: 25; other Solaris platforms in 5.0 and earlier: 32]
 
-XX:PermSize=
Initial size of permanent generation
 
-XX:MaxPermSize=64m
Size of the Permanent Generation.  [5.0 and newer: 64 bit VMs are scaled 30% larger; 1.4 amd64: 96m; 1.3.1 -client: 32m.]


下面所说通过优化程序算法来提高内存利用率,并降低内存风险,完全是经验之谈,仅供参考,如有不妥,请指正,谢谢!


1.尽早释放无用对象的引用(XX = null;)   

看一段代码:

 

Java代码  收藏代码
  1. public List<PageData> parse(HtmlPage page) {  
  2.         List<PageData> list = null;          
  3.         try {  
  4.             List valueList = page.getByXPath(config.getContentXpath());  
  5.             if (valueList == null || valueList.isEmpty()) {  
  6.                 return list;  
  7.             }  
  8.             //需要时才创建对象,节省内存,提高效率  
  9.             list = new ArrayList<PageData>();  
  10.             PageData pageData = new PageData();  
  11.             StringBuilder value = new StringBuilder();  
  12.             for (int i = 0; i < valueList.size(); i++) {  
  13.                 HtmlElement content = (HtmlElement) valueList.get(i);  
  14.                 DomNodeList<HtmlElement> imgs = content.getElementsByTagName("img");  
  15.                 if (imgs != null && !imgs.isEmpty()) {  
  16.                     for (HtmlElement img : imgs) {  
  17.                         try {  
  18.                             HtmlImage image = (HtmlImage) img;  
  19.                             String path = image.getSrcAttribute();  
  20.                             String format = path.substring(path.lastIndexOf("."), path.length());  
  21.                             String localPath = "D:/images/" + MD5Helper.md5(path).replace("\\", ",").replace("/", ",") + format;  
  22.                             File localFile = new File(localPath);  
  23.                             if (!localFile.exists()) {  
  24.                                 localFile.createNewFile();  
  25.                                 image.saveAs(localFile);  
  26.                             }  
  27.                             image.setAttribute("src""file:///" + localPath);  
  28.                             localFile = null;  
  29.                             image = null;  
  30.                             img = null;  
  31.                         } catch (Exception e) {  
  32.                         }  
  33.                     }  
  34.                     //这个对象以后不会在使用了,清除对其的引用,等同于提前告知GC,该对象可以回收了  
  35.                     imgs = null;  
  36.                 }  
  37.                 String text = content.asXml();  
  38.                 value.append(text).append("<br/>");  
  39.                 valueList=null;  
  40.                 content = null;  
  41.                 text = null;  
  42.             }  
  43.             pageData.setContent(value.toString());  
  44.             pageData.setCharset(page.getPageEncoding());             
  45.             list.add(pageData);  
  46.             //这里 pageData=null; 是没用的,因为list仍然持有该对象的引用,GC不会回收它  
  47.             value=null;  
  48.             //这里可不能 list=null; 因为list是方法的返回值,否则你从该方法中得到的返回值永远为空,而且这种错误不易被发现、排除  
  49.         } catch (Exception e) {              
  50.         }          
  51.         return list;  
  52. }  


2.谨慎使用集合数据类型,如数组,树,图,链表等数据结构,这些数据结构对GC来说回收更复杂。
3.避免显式申请数组空间,不得不显式申请时,尽量准确估计其合理值。
4.尽量避免在类的默认构造器中创建、初始化大量的对象,防止在调用其自类的构造器时造成不必要的内存资源浪费
5.尽量避免强制系统做垃圾内存的回收,增长系统做垃圾回收的最终时间
6.尽量做远程方法调用类应用开发时使用瞬间值变量,除非远程调用端需要获取该瞬间值变量的值。
7.尽量在合适的场景下使用对象池技术以提高系统性能

 

 

原创文章,转载请注明出处:http://yshjava.iteye.com/blog/1328015

 

分享到:
评论

相关推荐

    30+个视频+深入理解Java虚拟机(jvm优化+内存模型+虚拟机原理)

    30+个视频+深入理解Java虚拟机(jvm优化+内存模型+虚拟机原理)

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

    java虚拟机分析与优化PPT(演讲:李镭) 李镭——现任IBM中国有限公司软件部WebSphere高级工程师。 2002年加入IBM公司软件部,至今一直从事中间件产品家族的售前和售后工作。为IBM的重要合作伙伴提供软件的技术支持和...

    深入解析ANDROID虚拟机

    分别讲解了android系统基础知识,android系统的结构和核心框架,Java虚拟机和Dalvik虚拟机的知识,实现程序编译和调试,Dalvik的运作流程,DEX优化和安全管理,Android虚拟机生命周期的管理和内存分配策略,...

    Java虚拟机

    第二部分讲解了JVM的自动内存管理,包括虚拟机内存区域的划分原理以及各种内存溢出异常产生的原因;常见的垃圾收集算法以及垃圾收集器的特点和工作原理;常见虚拟机监控与故障处理工具的原理和使用方法。第三部分...

    Java虚拟机体系结构深入研究总结

     要对Java程序进行内存优化和性能调优,不了解虚拟机的内部原理(或者叫规范更严谨一点)是肯定不行的,这里推荐一本好书《深入Java虚拟机 (第二版)》(Bill Venners著,曹晓刚 蒋靖 译,实际上本文正是作者阅读本书...

    深入理解_Java_虚拟机 JVM_高级特性与最佳实践

    第2章 Java内存区域与内存溢出异常 / 24 2.1 概述 / 24 2.2 运行时数据区域 / 25 2.2.1 程序计数器 / 25 2.2.2 Java虚拟机栈 / 26 2.2.3 本地方法栈 / 27 2.2.4 Java堆 / 27 2.2.5 方法区 / 28 2.2.6 运行...

    高级java笔试题-understanding-the-jvm:《深入理解Java虚拟机》阅读笔记

    时进行的优化进行了总结,编译器优化部分尚未进行深入研究。 阅读方法: 本 repo 的 README.md 从头读到尾就是一个虚拟机大部分知识点的框架,就像一颗搜索树一样,我们想要了解哪一部分知识,就从根节点开始搜索,...

    JAVA虚拟机,看这篇就够了!

    小编给大家推荐腾讯课堂联合图灵学院出的一个 2 分钱课程《JVM虚拟机底层原理分析与性能优化》,看它到底是怎么样来实现我们常说常说的诸如JVM内存结构、内存调优、内存模型、以及理解高并发程序的开发精髓

    涵盖了 Java 基础、集合、源码、并发、虚拟机、框架、数据库、网络编程、设计模式、新特性和数据结构等多个知识领域的面试突击

    Java虚拟机:内存模型、垃圾收集器、类加载机制等 Java企业级开发:Spring、Hibernate、MyBatis等框架原理 数据库和缓存:SQL优化、索引、Redis、Memcached等 分布式系统:负载均衡、集群、分布式事务、分布式锁等 使用...

    Java 虚拟机面试题全面解析(干货)

    Java 虚拟机面试题全面解析,《深入理解Java虚拟机》干货版,自己总结,希望能够帮助大家,免费下载~什么是类加载机制? 虚拟机和物理机的区别是什么? 运行时栈帧结构 Java方法调用 什么是方法调用? Java的方法调用,...

    最详细的java内存讲解

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

    论文研究-JavaServlet模式的WebGIS性能优化研究.pdf

    因此对WebGIS服务器端性能问题进行了深入研究,提出了JVM(Java虚拟机)性能调优、建立并改进缓存服务器、使用tmpfs(一种基于内存的文件系统)存储缓存图片等从根本上解决服务器端性能问题的一系列方案,同时设计了...

    深入理解java虚拟机第二版源码-programmer_training_strategy:程序员练级攻略(2018)内提到的书籍、手册等

    深入理解java虚拟机 第二版 源码 程序员练级攻略(2018)内推荐书籍和手册 开篇词 入门篇 零基础启蒙 正式入门 修养篇 程序员修养 《完美软件》 专业基础篇 编程语言 理论学科 系统知识 软件设计篇 软件设计 高手...

    深入理解Java:String

    按照官方的说法:Java虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配。 JVM主要管理两种类型内存:堆和非堆,堆内存(HeapMemory)是在Java虚拟机启动时创建,非堆内存(Non-heap ...

    【Java正来-深入理解JVM】Java内存模型与线程.xmind思维导图

    可以先看我的博客在下载,...增加高速缓存;为了使得处理器内部的运算单元能尽量被充分利用,处理器可能会对代码进行乱序执行优化,处理器会在计算机之后将乱序执行的结果重组,保证该结果与顺序执行结果是一致的

    JVM 相关知识的脑图介绍

    JVM(Java虚拟机)是Java程序的运行环境,它是一个虚拟的计算机,负责将Java字节码解释成机器码并执行。JVM提供了内存管理、垃圾回收、安全性等功能,使得Java程序具有跨平台性。JVM的结构包括类加载器、解释器、...

    Java进阶教程解密JVM视频教程

    JVM 是 Java 程序的运行环境,学习 JVM,方能了解 Java 程序是如何被执行的,为进一步深入底层原理乃至程序性能调优打好基础。通过学习这门课程,你将掌握:1. JVM 内存结构的组成、各部分功能作用,学会利用内存...

    Notes:This is a learning note | Java基础,JVM,源码,大数据,面经

    深入理解Java虚拟机 Java内存区域划分与对象新建过程 jvm垃圾收集机制与内存分配策略 jvm类加载机制 Java的内存模型 锁优化 Think In Java Java容器 Java并发 Java Concurrency in Practice 对象的共享 对象的组合 ...

    JVM规范--高手总结

    JVM规范--高手总结 Java相关 1 1.1Java定义 1 1.2Java的开发流程 1 1.3Java运行的原理 2 1.4半编译半解释 3 1.5平台无关性 4 JVM内存模型 4 2.1 JVM规范 5 2.2 Sun JVM 8 ...Java虚拟机(JVM)参数配置说明 30

Global site tag (gtag.js) - Google Analytics