百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

LoadRunner性能测试系统学习教程:堆与栈(9)

cac55 2024-09-26 07:28 23 浏览 0 评论

上期我们讲到LoadRunner性能测JVM调优,这期我们讲LoadRunner性能测试堆与栈。

堆与栈

在上节介绍JVM内存模型时,发现JVM内存分为堆和栈两种,那么为什么需要将内存分为堆和栈两种呢?之所以分成两类是为了JVM在调用内存时更好的对内存进行管理。

在JAVA虚拟机中使用的数据又分为两类:一是基础数据;二是引用数据。基础数据是引用数据本身,引用数据是引用数据对象。

基础数据通常包括:

byte、short、int、long、char

float、double、Boolean、returnAddres。

引用类型包括:接口、类、数组。

栈是运行单位,所以的运行对象,都在是栈中。

当程序运行时JVM会为每个线程一个栈大小。每个线程栈是不通用的,因为每个任务都有一个独立的线程来执行。堆是存储单位,所以有需要使用的数据都在堆中,堆是可以共享的。也就是堆是处理的数据的地方,栈是用来处理的逻辑的地方。之所以分堆与栈,这样的好处是可以将业务逻辑与数据进行分离,同时也可以提高数据的共享程度。

从软件设计的角度来看,栈代表了处理逻辑,而堆代表了数据,这样将数据与逻辑分离可以让处理逻辑更为清晰。这种隔离、模块化的思想在软件设计的方方面面都有体现。

堆与栈的分离,使得堆中的内容可以被多个栈共享,但栈不管理Java栈还是方法栈其线程都是私有的,是无法共享的,所以这样就可以让数据被多个线程共享进行操作。

这种共享有很多好处,一方面提供了一种有效的数据交互方式(如内存共享),另一方面,节省了内存空间。

栈因为运行时的需要进行地段的划分。由于栈只能向上增长,因此会限制住栈存储内容的能力。而堆不同,堆的大小可以根据需要动态增长。因此,堆与栈的分离,使得动态增长成为可能,相应栈中只需要记录堆中的一个地址即可。

PermGen与Metaspace区别

在java8之前JVM第三代都是持久代PermGen,

在java8和之后的版本都是Metaspace元空间。

持久代PermGenspace的全称是

PermanentGenerationspace

是指内存的永久保存区域,那么为什么会出现内存溢出呢?

这是因为存放Class的信息在被加载时会放入到持久代PermGenspace区域,如果出现很多Class的话

那么就会可能出现PermGenspace错误。

JVM类型也很多种,比如

Oralce-SunHotspot、ralceJRockit、IBMJ9

TaobaoJVM等等。当然用的最多的还是Hotspot。

需要注意的是,PermGenspace是Oracle-SunHotspot才有,JRockit以及J9是没有这个区域。一般现在讨论的多的是Hotspot的JVM,所以通常会说持久代。

持久代中包含了虚拟机中所有通过反射获取到的数据,如类和方法对象,不同的Java虚拟机之间可能会进行类的共享操作,因此持久代又分为只读区和读写区。关于JVM运行时会使用到多少持久代的空间取决于应该程序用到了多少类。

除此之外,JavaSE库中的类和方法也都存储在这里。当JVM对类的操作完成后,发现不再需要使用这个类时,就会将这个类释放出来,释放的空间需要使用FullGC进行回收。

那么持久代是如何来设置呢?在JVM中可以通过MaxPermSize参数来设置,默认值为64M,Java堆中分配的区域尽量是连续的,如果非连续的堆空间,那要定位出持久代到新对象的引用是非常复杂的也是很耗时的。

在堆中有一种记忆集叫卡表,可以记录某个内存在普通对象指针的修改情况。当持久代都使用了后,系统就会抛出OutOfMemoryError的异常信息,当然解决的办法就是清理了不用的类或者增加MaxPermSize的值。

那么在现在的JVM中为何将原来的持久代取消了呢?因为原来的持久代有以下一些缺点:

1)以前的版本中PermGen会存储一些字符串,PermGen内存的大小是通过-xx:PermSize这个参数来设置的,但是由于字符串池的大小经常是变化的,导致设置-xx:PermSize

这个参数变的困难这样很容易出现

OOM提示的错误

java.lang.OutOfMemoryError:PermGenspace。

2)以前将方法主要存储在PermGen,

现在将方法都移动Metaspace,Metaspace不在JVM中

而是在本地的内存。

3)减少经常使用FullGC的频率。

根据上面的各种原因,永久代最终被移除

永久代移除后,原来永久代中的方法区移至Metaspace元空间中,字符串常量移至JavaHeap堆中。

Metaspace元空间由两大部分组成:

KlassMetaspace和NoKlassMetaspace。

1)KlassMetaspace

KlassMetaspace是用来存放klass的,就是class文件在JVM中运行时的数据结构,这部分内存空间默认放在

CompressedClassPointerSpace中

是一个连续的内存区域块,紧接着Heap堆

在JVM中可以

-XX:CompressedClassSpaceSize

来控制这块内存大小默认值为1G。

CompressedClassPointerSpace不是必须存在的

如果设置了

-XX:-UseCompressedClassPointers

或者设置的-Xmx值大于32G,那么这块内存就不会存在

这种情况下klass就会存在

NoKlassMetaspace中。

2)NoKlassMetaspace

NoKlassMetaspace专门来存klass相关的其它内容,

如method、constantPool等,它可以是多个不连续的内存组成。

这块内存是必须的,不能不存在,并且是在本地内存中进行分配。

KlassMetaspace和NoKlassMetaspace两个部分的内存空间是所有类加载器都可以共享的,当然这些加载器都需要分配内存,为了更好的管理这些类加载器,每个类加载器都有一个SpaceManger空间管理来管理这些类加载器如何分配内存大小。分配的内存都是来自于实内存,如果KlassMetaspace用完了,那么就会提醒OutOfMemoryError异常,

但一般的情况下是不会出现这种情况的,NoKlassMetaspace是由一小块一小块内存累加起来的。

元空间和持久代在使用内存上是很类似的,都是对JVM规范中方法区的实现,但是他们分配内存是不同的,持久代内存是在虚拟机中,但是元空间是本地内存,所以正常情况下元空间的大小不受限制,如果说受限制那只是受本地内存限制,并且元空间一般是不可能会出现OutOfMemoryError异常的。设置元空间大小一般可以通过以下几个参数来实现:

1)-XX:MetaspaceSize

-XX:MetaspaceSize,初始空间大小,达到该值就会触发垃圾收集进行类型卸载,同时GC会对该值进行调整:如果释放了大量的空间,就适当降低该值;如果释放了很少的空间,那么就会提高该元空间的值。

但不管怎么提高或增加元空间的值,都不能超过MaxMetaspaceSize所设置的值。

2)-XX:MaxMetaspaceSize

-XX:MaxMetaspaceSize表示元空间可以达到的最大值,默认是没有限制的,取决于机器的内存,限制类的元数据使用的内存大小,以免出现虚拟内存切换以及本地内存分配失败。如果怀疑有类加载器出现泄露,应当设置这个参数;元空间的初始大小是21M,这是GC的初始的高水位线,超过这个大小会进行FullGC来进行类的回收。如果启动后GC过于频繁,请将该值设置得大一些,可以设置成和持久代一样的大小,这个GC可以不用那么频繁的执行。

3)-XX:MinMetaspaceFreeRatio

-XX:MinMetaspaceFreeRatio表示GC之后,最小的Metaspace剩余空间容量的百分比,目的是控制减少为分配空间所导致的垃圾收集。

MinMetaspaceFreeRatio和下面的

MaxMetaspaceFreeRatio,

主要是影响触发metaspaceGC的阈值。默认值为40,表示每次GC完之后

如果metaspace内存的空闲比例小于

MinMetaspaceFreeRatio%

那么将尝试做扩容。

增大触发metaspaceGC的阈值。不过这个增量至少是MinMetaspaceExpansion才会做,不然不会增加这个阈值。

这个参数主要是为了避免触发metaspaceGC的阈值和GC之后committed的内存的量比较接近,于是将这个阈值进行扩大。

注:这里不用GC之后used的量来算

主要是担心可能出现committed的量超过了触发metaspaceGC的阈值,这种情况一旦发生会很危险,会不断做GC。

4)-XX:MaxMetaspaceFreeRatio

-XX:MaxMetaspaceFreeRatio表示GC之后,最大的Metaspace剩余空间容量的百分比,目的是控制减少为释放空间所导致的垃圾收集。默认值为70,这个参数和上面的参数基本是相反的,是为了避免触发metaspaceGC的阈值过大,而想对这个值进行缩小。这个参数在GC之后committed的内存比较小的时候并且离触发metaspaceGC的阈值比较远的时候才进行调整。

5)-verbose

-verbose通过这个参数可以获取类型加载和卸载的信息。

那么元空间这些内存是怎么来管理和分配或者说回收的呢?元空间的内存管理是由元空间虚拟机来管理,通常说的一个元空间是指一个类加载器的存储区域,当然所有元空间合在一起就称之为元空间,以前对于类的元数据需要不同的垃圾回收器来进行处理,但现在只需要执行虚拟机的C++代码即可以完成,并且类和其元数据的生命周期与类加载器是相同的,如果类加载器还是存活的话,那么类的元数据也是存活的,这个时候是不会被回收。当一个类加载器被垃圾回收器标记为不再存活时,其对应的元空间就会被回收。

元空间虚拟机负责元空间的分配,其采用的形式为组块分配,组块的大小因类加载器的类型而异,在元空间虚拟机中存在一个全局的空闲组块列表,当一个类加载器需要一个组块时,它就会从这个全局的组块列表中获取,并不断的维持一个属于自己的组块列表,当类加载器不再存活时,这个组块也就会被释放,并返回给全局组块列表,类加载器拥有的组块会被分成很多个块,每个块存储一个单元的元信息,组块中的每个块是线性分配的,组块分配自内存映射区域。这些全局的虚拟内存映射区域以链表形式连接,一旦某个虚拟内存映射区域清空,这部分内存就会返回给操作系统。

如果需求监控Metaspace元空间的信息,可以使用JDK自带的一些工具来展示Metaspace的详细信息:

  • 针对Metaspace,JDK自带的一些工具做了修改来展示Metaspace的信息:
  • jmap-clstats:打印类加载器的统计信息(取代了在JDK8之前打印类加载器信息的permstat)。
  • jstat-gc:Metaspace的信息会被打印出来。
  • jcmdGC.class_stats:这是一个新的诊断命令,可以使用户连接到存活的JVM,转储Java类元数据的详细统计。

相关推荐

服务器用的CPU和个人电脑用的CPU有什么区别?一篇文章告诉你!

服务器cpu和普通cpu的区别你的电脑CPU是‘短跑健将’,服务器CPU却是‘铁人三项选手’——它不追求瞬间爆发力,而要7×24小时扛住千军万马的数据洪流!想知道为什么企业机房敢收天价服务费?答案全藏...

“吃鸡”新版本第1天,玩家进入游戏点击“立即更新”,后悔了!

欢迎诸位小伙伴们来到天哥开讲的《和平精英》“精英小课堂”~每逢两三个月,这款游戏就会迎来一次大版本迭代更新,很多朋友会在第一时间更新版本,前往全新的主题模式里一探究竟。不过也有一些老玩家并不会立刻更新...

中关村在线·aigo存储杯《无畏契约》全国高校争霸赛招募启事

以青春之名,燃电竞之火1赛事背景与宗旨在金秋送爽的9月,芊芊学子们即将回归校园生活。为了给精彩的校园生活锦上添花,由中关村在线与aigo存储联合主办的《无畏契约》全国高校争霸赛正式启幕,旨在为全国高...

【生肖狗】9.7-9.10提醒:人算不如天算,转变即是转机

九月上旬的风,带着秋意的清爽,也带着几分不可捉摸的变数。对于生肖狗的朋友们来说,9月7日到9月10日这四天,格外需要留意“计划与变化”的碰撞——你们向来习惯提前规划,做事稳妥周全...

转转客服IM系统的WebSocket集群架构设计和部署方案

本文由转转技术李帅分享,原题“转转客服IM的WebSocket集群部署方案”,下文有修订和重新排版。1、引言转转作为国内头部的二手闲置交易平台,拥有上亿的用户。用户在使用转转app遇到问题时,一般可以...

上线3天Steam好评率86%,《时间旅者:重生曙光》开启生存恐怖新篇章

这里究竟发生了什么?末日降临,真正的故事悄然启幕。目前,生存恐怖类游戏《时间旅者:重生曙光(Cronos:TheNewDawn)》已在PC(Steam、EpicGamesStore)、P...

什么神仙洗衣机让我一天有28小时?拆开松下「大四洗」藏了啥秘密

说起家庭洗衣的烦恼,想必很多人都有过类似的经历:贴身内衣要单独洗,宝宝的口水巾得小心呵护,宠物玩具怕藏污纳垢,床单被套又体积庞大,把这些东西混在一起洗担心越洗越脏,分开洗又得反复操作,洗完烘、烘完再洗...

爆料人挖出GTA6注册的奇葩域名 延续经典讽刺风格

等待《侠盗猎车手6》的日子跨越了数个春秋,在游戏圈期盼着这部可能成为史上最重磅游戏的过程中,每过一段时间就会有些许消息浮出水面。最新线索来自数据挖掘者Tez2在GTA论坛的发现,他可能偶然发现了关于...

跟着故事去旅行——读《驼峰间:旅行、探险与征服》

作者:郭冰茹《驼峰间》记录了旅行家伊本·白图泰有生之年流传的一则寓言,说一对父子被关进了监狱,有一天儿子问父亲他们每天吃的都是些什么肉,父亲说有牛、羊和骆驼,并且详细地描述了每种动物的特点。但不管父亲...

前端工程师需要熟悉的Linux服务器(SSH 终端操作)指令

在Linux服务器管理中,SSH(SecureShell)是远程操作的核心工具。以下是SSH终端操作的常用命令和技巧,涵盖连接、文件操作、系统管理等场景:一、SSH连接服务器1.基本连接...

跳票6年后,「丝之歌」首发把Steam服务器干爆了 | 玩点好的

文丨果脯樱花隧道昨天晚上22点,「鸽」了6年的《空洞骑士:丝之歌》终于上线,算是了却不少玩家的执念。毕竟,这款游戏实在让人等了太多太多年,而且曾有过多次定档后跳票的「案底」,不知道把多少人都整出了P...

对标魔兽失败!腾讯版“魔兽”运营一年多后,宣布国际服凉凉

大家好,这里是正惊游戏,我是正惊小弟。有很多游戏都想干掉《魔兽世界》,但是大部分魔兽杀手都知道自己不是魔兽的对手,不过是想蹭一下人气而已。腾讯也有一款曾经想对标魔兽的大作,可是上线才一年半国际服就宣布...

408 Request Timeout:服务器等待客户端发送请求的时间过长。

408RequestTimeout是HTTP状态码之一,表示客户端在发送请求时,服务器等待的时间过长,最终放弃了处理该请求。此问题通常与网络延迟、客户端配置、服务器设置或者应用程序的性能有关...

梦幻西游:9.9维护解读,全新时间服锁定129级

梦幻西游:9.9维护解读,全新时间服锁定129级9月9日维护解读。1、教师节活动开启,一共7天。挂机,答题,收笔墨纸砚,收海马,搞起来。或者是提前收点家具,教师节期间体力珍贵,家具会涨价。又或者是教师...

只是拆掉一面墙,空间就立马大变样,这种设计思路,值得学习

你有没有过这样的经历?刚买的房子户型图看起来方方正正,装修完却发现——玄关鞋柜只能塞在角落,进门就撞墙;餐厅正好在过道中间,吃饭像走流程;明明有四个房间,却有一个空着没用,像块食之无味的鸡肋;客餐厅之...

取消回复欢迎 发表评论: