• 13
  • 13
分享
  • 从容应对问题再发:浅析JVM内存结构——软件测试圈
  • 曼倩诙谐 2022-03-16 10:33:39 字数 2633 阅读 1476 收藏 13

  JVM内存是我们在系统部署、优化、问题排查中的一项重要内容,在最近支持的几个项目中,多次出现与JVM内存相关的问题,因此有必要加强一下实施人员对JVM内存的理解,从而更好地应对今后可能再次出现的问题。

  关于JVM内存相关理论的文章,网上有很多,下面的内容是参照网络文章并结合我们实际工作中的问题做出的一些总结,重点在JVM的内存结构上,供大家参考。

  公式一

  JVM在我们看来,就是一个java进程,无论我们的系统使用的是tomcat、weblogic、还是websphere,系统起来后对应的就是一个java进程。这个java进程的内存组成可以粗略的用下面的公式来表示:

  JAVA进程内存(或者叫作JVM内存)=堆内存+类存储内存+堆栈内存+其它内存

  堆内存:就是heap内存,就是通过-Xms和-Xmx设置的那部分内存,这部分内存主要存储java对象,例如new生成出来的对象,这部分内存可以通过垃圾回收器进行回收。

  类存储内存:是专门存储java类的内存,例如系统启动时装载的第三方jar包,应用服务器本身的类,编译jsp后形成的java类等,都是存在这个区域的,这部分内存基本不会被垃圾回收器回收,只有在某些特殊情况下才会被回收。不同厂商对于这部分内存的实现不尽相同,例如Sun的jdk中,是通过-XX:PermSize和-XX:MaxPermSize来设置的,而IBM的jdk则没有这个区域,而是存在堆内存中的。

  堆栈内存:即stack内存,主要用于存储线程用到的相关数据,栈中主要存放一些基本类型的变量(int, short, long, byte, float, double, boolean, char)和对象句柄。

  线程堆栈内存:通过-Xss参数来指定,默认值在256KB到756KB不等,假设线程堆栈设置为-Xss512k,系统运行期间共有200个线程,那么线程堆栈总的占用内存大概就是100M,运行线程数量越多,堆栈占用内存也就越大。

  其它内存:主要包括JIT、JNI、NIO等,这些内存比较复杂,这里不做过多介绍。

  公式二

  上面介绍的JAVA进程内存都是指用户空间的内存,除了用户空间内存,还有一部分内核空间内存,内核空间内存供操作系统使用,对于应用程序来说是透明的不可访问的。

  对于上面的公式,可以进一步细化为如下公式:

  JAVA进程内存=用户空间内存(堆内存+类存储内存+堆栈内存+其它内存)+内核空间内存

  有了这个公式,我们在理解以下问题时就比较清晰了。

  问题一:32位jdk和64位jdk的最大内存问题。

  32位jdk的-Xmx值最大可以设置多大,这个问题是我们在实施过程中经常遇到的。

  对于32位系统,单个进程内存的最大寻址空间为2的32次方,也就是4GB内存,其中一部分是用户空间内存,一部分是内核空间内存。对于windows系统,内核空间默认是预留2GB,用户空间最大只有2GB,用户空间除了有堆内存,还有其它类型的内存,所以-Xmx的最大值一定是小于2G,通常最大能设置到1536M。

  对于linux系统,内核空间默认是预留1GB,用户空间最大可以到3GB,所以-Xmx的最大值一定是小于3G,通常至少可以设置到2048M以上。

  对于64位系统,单个进程内存的最大寻址空间为2的64次方,非常大了,基本可以当作没有限制,所以-Xmx的最大值可以认为是无限大。

  注:可以通过java –Xmx****** -version来测试最大可设置的堆内存。

  问题二:内存溢出的分类及应对。

  当出现内存溢出时,首先要搞清楚是哪部分内存溢出,这样才能采取相应的应对措施。

  A.堆内存溢出

  错误日志:

java.lang.OutOfMemoryError: Java heap space

  解决方案:检查-Xmx设置是否合理;通过工具分析javacore和heapdump定位问题。

  B.类存储内存溢出

  该类问题通常只出现在sun的jdk中,错误日志大致如下:

java.lang.OutOfMemoryError: PermGen space

  解决方案:增加-XX:MaxPermSize的值。

  C.堆栈内存溢出

  错误日志:

java.lang.StackOverflowError

  解决方案:通常是代码中有死循环或循环次数太多导致,也可以适当增加-Xss参数值。

  D.用户空间内存溢出(也叫本机内存溢出)

  错误日志:

java.lang.OutOfMemoryError: Failed to fork OS thread
java.lang.OutOfMemoryError:requested 32756 bytes for ChunkPool::allocate.Out of swap space?
The system is out of physical RAM or swap space In 32 bit mode, the process size limit was hit.

  解决方案

  1、物理内存不足,增加物理内存。

  2、Jdk的bug,升级或更换jdk。

  3、物理内存充足的情况下出现本机内存溢出,一定是在32位系统中才会出现,最好的解决方案就是换成64位系统,如果无法更换的话只能通过适当调整JAVA用户空间内存中各组成部分的大小来尝试解决。

  例如在32位windows系统中,用户空间内存最大值为2G,堆内存-Xmx设置了1536M,这样其它非堆的内存部分只可以使用不到500M的内存,如果500M不够用的话,就会出现本机内存溢出,这时可以将-Xmx调小,例如调小到1024M(保证够用不会出现堆内存溢出),这样非堆的内存就增加到了1024M,问题有可能就得到解决。

  关于本机内存溢出的原因可能会比较复杂,需要根据实际情况具体问题具体分析。

  通过以上总结和分析,希望大家再次遇到内存溢出问题时能理清思路,对症下药。目前内存价格相对便宜,很多客户配置的物理内存都会超过4G,为了减少内存溢出问题的发生,可以建议用户都采用64位的操作系统,相关的jdk、应用服务器、数据库也都采用64位的,这样也可以使资源得到充分利用。



作者:云竹   

来源:http://www.51testing.com/html/92/n-4481592.html

  • 【留下美好印记】
    赞赏支持
登录 后发表评论
+ 关注

热门文章

    最新讲堂

      • 推荐阅读
      • 换一换
          •   一、什么是自动化测试框架?  自动化测试框架是为自动化测试用例或者脚本提供执行环境而搭建的基础设施。自动化测试框架有助于有效地开发、执行和报告自动化测试用例。  优点:  · 代码复用  · 提高测试效率  · 更高的测试覆盖率  · 维护成本低  · 更早发现和记录bug  二、框架的基本组成  1、配置文件管理:  一般需要一个配置文件去控制一些环境信息、开关。配置文件可以是txt/xml/yaml/properties/ini,一般.propertis使用较多在JAVA里,Python的话通常会选择ini文件。  2、业务逻辑代码和测试脚本分离...
            0 0 1068
            分享
          •   关键要点  ·由于软件开发过程具有复杂性,所以它很难被理解。  ·正是这种复杂性,导致了许多来源不明的信条和直觉。  ·最近一项对软件开发过程的研究结果挑战了许多普遍持有的观点。  ·一些不太容易理解的研究结果揭示了开发过程中意想不到的力量。  ·在软件开发中,非技术因素对整个项目的影响往往胜过技术因素。  最近,我看到了一项关于项目中所使用的编程语言和代码质量相关性方面的研究。?我非常感兴趣,因为研究结果和我预想的截然相反。一方面,这项研究可能有缺陷,另一方面,许多在软件开发中已确立的实践和信念来源不明。我们遵守这些实践和信念是因为“每个人”都在这样做,或者它们被认为是最佳实践,或者它们...
            11 11 1787
            分享
          •   测试工作五年后一般怎样了?  五年测试生涯对身体上的摧残就不说了,来讲讲一般会有怎样的状态吧!  优秀的一般是这样:有着明确的职业目标与规划,热爱技术,五年的工作沉淀,技术能力得到了飞速提升,每天依然激情满满,潜心专研学习技术,是身边同事羡慕的对象,是老板眼中的优秀员工,也是我眼中的技术大佬,薪资嘛自然也是水涨船高。  普通的一般是这样:也许跳槽了多次,薪资也在稳步的上涨中,但也多了些许空虚与迷茫,意识到自已只是茫茫程序员中普通的那一个,每天按部就班地工作、学习、生活,憧憬着有朝一日成为技术牛人。  差劲的一般是这样:工作只是为了生活,对技术缺乏热爱,虽也保持着学习的节奏,但质跟量都不太行...
            1 1 1278
            分享
          •   有媒体报道称,特斯拉正在向美国州政府寻求近1亿美元的资金,用于在从美国得克萨斯州南部边境到加利福尼亚州北部的一条路线上带头建造9个电动化的半挂卡车充电站。据媒体报道,特斯拉高管在5月至7月初之间写给得克萨斯州交通部的数封电子邮件中表示,该公司建议为特斯拉Semi卡车配备8个750kw的充电桩,为竞争对手生产的卡车配备4个充电桩。  据了解,如果成功获批,这将是美国首个此类充电网络。它将实现从得克萨斯州到加利福尼亚州的长途电气化卡车运输,以及得克萨斯州、亚利桑那州和加利福尼亚州的区域长途卡车运输。美国严重依赖商用卡车运输货物,但一直在努力限制该行业的温室气体排放量。  特斯拉的高管们告诉得州...
            0 0 685
            分享
          • 前言本文主要是记录Pycharm创建支持appium模块的项目时,如何安装Appium-Python-Client以及通过一个简单的脚本实现自动点击操作的过程。步骤1.创建python项目使用Pycharm新建一个项目,这里取名test,如下图创建完以后,会自动生成一些文件,如下图:2.添加Appium-Python-Client2.1 打开Settings对话框在项目的菜单中选择File->Settgings(或者直接按快捷键Ctrl+Alt+S)2.2 安装Appium-Python-Client选择Project:test(test为项目名,不同项目不一样)下的Project In...
            13 13 2638
            分享
      • 51testing软件测试圈微信