Java虚拟机内存优化的方法
这篇文章主要介绍“Java虚拟机内存优化的方法”,在日常操作中,相信很多人在Java虚拟机内存优化的方法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java虚拟机内存优化的方法”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
前面一篇文章介绍了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.]
下面所说通过优化程序算法来提高内存利用率,并降低内存风险,完全是经验之谈,仅供参考,如有不妥,请指正,谢谢!
尽早释放无用对象的引用(XX = null;)
看一段代码:
public List<PageData> parse(HtmlPage page) { List<PageData> list = null; try { List valueList = page.getByXPath(config.getContentXpath()); if (valueList == null || valueList.isEmpty()) { return list; } //需要时才创建对象,节省内存,提高效率 list = new ArrayList<PageData>(); PageData pageData = new PageData(); StringBuilder value = new StringBuilder(); for (int i = 0; i < valueList.size(); i++) { HtmlElement content = (HtmlElement) valueList.get(i); DomNodeList<HtmlElement> imgs = content.getElementsByTagName("img"); if (imgs != null && !imgs.isEmpty()) { for (HtmlElement img : imgs) { try { HtmlImage image = (HtmlImage) img; String path = image.getclass="lazy" data-srcAttribute(); String format = path.substring(path.lastIndexOf("."), path.length()); String localPath = "D:/images/" + MD5Helper.md5(path).replace("\\", ",").replace("/", ",") + format; File localFile = new File(localPath); if (!localFile.exists()) { localFile.createNewFile(); image.saveAs(localFile); } image.setAttribute("class="lazy" data-src", "file:///" + localPath); localFile = null; image = null; img = null; } catch (Exception e) { } } //这个对象以后不会在使用了,清除对其的引用,等同于提前告知GC,该对象可以回收了 imgs = null; } String text = content.asXml(); value.append(text).append("<br/>"); valueList=null; content = null; text = null; } pageData.setContent(value.toString()); pageData.setCharset(page.getPageEncoding()); list.add(pageData); //这里 pageData=null; 是没用的,因为list仍然持有该对象的引用,GC不会回收它 value=null; //这里可不能 list=null; 因为list是方法的返回值,否则你从该方法中得到的返回值永远为空,而且这种错误不易被发现、排除 } catch (Exception e) { } return list; }
谨慎使用集合数据类型,如数组,树,图,链表等数据结构,这些数据结构对GC来说回收更复杂。
避免显式申请数组空间,不得不显式申请时,尽量准确估计其合理值。
尽量避免在类的默认构造器中创建、初始化大量的对象,防止在调用其自类的构造器时造成不必要的内存资源浪费
尽量避免强制系统做垃圾内存的回收,增长系统做垃圾回收的最终时间
尽量做远程方法调用类应用开发时使用瞬间值变量,除非远程调用端需要获取该瞬间值变量的值。
尽量在合适的场景下使用对象池技术以提高系统性能
到此,关于“Java虚拟机内存优化的方法”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341