Java 程序优化知识笔记

迁移64位虚拟机未必性能更好

业务量上升以后,需要使用的内存随之增加,而在通常32位系统上,单个进程占用的最大内存通常是2GB,且考虑到堆外内存的使用,32位机器可能无法满足内存要求,一种常见的应对方式就是换用64位服务器。而对于Java,由于指针膨胀和字节对齐,同一个程序在64位虚拟机上占用的内存会多于32位虚拟机。开发者换用64位虚拟机后,很可能会增加虚拟机的堆大小,而这将导致 Full GC 垃圾回收的时间大大增加,导出堆快照也变得困难。

因此,使用64位虚拟机增加内存时,需要特别注意对内存的使用,尽量不要触发Full

GC导致长时间停顿。另一种方法是建立32位虚拟机的集群来提高性能。

堆外内存溢出

Java本地方法调用,如调用C++实现的本地模块、NIO的DirectByteBuffer,都会占用大量内存。而在开发中,开发者往往重点关注了堆内存的大小,在内存溢出时也倾向于增加堆内存,而忽视了堆外内存的使用。堆外内存并不会像堆内存一样不足马上通知GC进行垃圾回收,堆外内存只能等待老年代空间不足进行Full

GC时顺便回收内存,否则堆外内存只能等到空间不足时抛出内存溢出异常,然后请求GC进行回收。

因此,配置虚拟机,除考虑常规的堆大小外,优化时还需要考虑Direct

Memory、线程栈、socket缓冲区、JNI代码、虚拟机、GC占用的内存大小。

外部命令的时间消耗

Java开发中如果需要执行shell脚本,可以使用Runtime.getRuntime().exec方法,还能从返回的Process对象中读取标准输出、错误输出、等待执行结束。根据方法注释,该方法首先复制当前进程产生一个子进程,在子进程中执行命令,结束后退出子进程。

进程的复制比较消耗CPU和内存,应尽量通过Java程序本身去完成相关功能。

多线程使用线程池

Java虚拟机中没有给用户用的多进程方法,并行处理更多地使用多线程方式。默认情况下,Linux限制用户的线程数量上限为1024,当然包括了系统中运行的所有线程。通常情况下,线程资源不会被耗尽,但多线程程序如果频繁创建新线程也会遇到线程资源不足的情况。一方面,可以调整系统设置,提高线程数上限,另一方面,应尽量避免频繁创建线程。线程虽小,创建时一样要消耗时间和内存。

多线程程序应尽量采用Java的线程池,这样线程的个数总体可控,使用时可以避免创建线程的时间消耗。Java提供了多种功能强大的线程池类型,基于线程池可以对任务进行缓存、按照一定的时间频率执行任务、返回执行结果、分叉与合并等。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,486评论 11 349
  • Java8张图 11、字符串不变性 12、equals()方法、hashCode()方法的区别 13、...
    Miley_MOJIE阅读 9,154评论 0 11
  • 1.1 概述 Java优点: 1、结构严谨,面向对象 2、摆脱硬件平台束缚,实现了“一次编写,到处运行”的理想; ...
    viciyforever阅读 4,976评论 1 9
  • http://www.cnblogs.com/angeldevil/p/3801189.html值得一看 Clas...
    snail_knight阅读 5,378评论 1 0
  • 时间不可管理, 可以管理的是自己的心智。 深信积累的力量,把时间当做朋友,而不是敌人 不同的心智模型,决定了两种执...
    Tim爱运营阅读 1,409评论 0 0

友情链接更多精彩内容