如何判断内存泄漏内存泄露是指使用内存完成后没有释放 , 内存增长并不能分辨增长出来的内存是进程真正要用的,还是进程泄露出来的 。而CPU的占用是瞬时的、确定的 , 不存在某个进程申请了CPU占着不用的情况 。在稳定性测试(也叫持久测试或疲劳测试)中 , 需要观察内存是否有泄露 。然而使用内存的进程千千万,整个服务器的内存增长似乎也不能判断某个进程的内存有泄露 。因此在稳定性测试过程中往往需要全程关注指定进程的内存消耗,比如运行3天、7天 。
查看内存使用情况的命令有ps、sar、svmon、vmstat等等,但本文并不从工具使用的角度来介绍,而是从性能测试中关注指标的角度来介绍 。如果采用其他命令查看内存,需注意,相似的名字在不同命令当中的含义是不一样的,一定要搞清楚这个字段的真正含义 。
例1:Virtual这个词 , 有时候在内存里面指Paging Space(换页空间),有时指进程空间里面占用的所有分页(包括物理内存和Paging Space中的分页) 。
例2:Nmon中的PgIn/PgOut、topas中的PageIn/PageOut是指对文件系统的换页,而vmstat中的pi/po是对Paging Space的换页,而topas P中进程的PAGE SPACE是指进程的Data Segment 。
java程序内存溢出一般什么原因JVM内存设置小了 或者一次性读的数据过大 例如list vertor
一、内存溢出类型
1、java.lang.OutOfMemoryError: PermGen space
JVM管理两种类型的内存java内存泄漏代码特征 , 堆和非堆 。堆是给开发人员用的上面说的就是,是在JVM启动时创建;非堆是留给JVM自己用的 , 用来存放类的信息的 。它和堆不同,运行期内GC不会释放空间 。如果web
app用了大量的第三方jar或者应用有太多的class文件而恰好MaxPermSize设置较?。?超出了也会导致这块内存的占用过多造成溢出,或者tomcat热部署时侯不会清理前面加载的环境,只会将context更改为新部署的,非堆存的内容就会越来越多 。
PermGen space的全称是Permanent Generation
space,是指内存的永久保存区域,这块内存主要是被JVM存放Class和Meta信息的,Class在被Loader时就会被放到PermGen
space中,它和存放类实例(Instance)的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对PermGen
space进行清理,所以如果java内存泄漏代码特征你的应用中有很CLASS的话,就很可能出现PermGen space错误 , 这种错误常见在web服务器对JSP进行pre
compile的时候 。如果你的WEB APP下都用了大量的第三方jar, 其大小超过了jvm默认的大小(4M)那么就会产生此错误信息了 。
一个最佳的配置例子:(经过本人验证,自从用此配置之后,再未出现过tomcat死掉的情况)
set JAVA_OPTS=-Xms800m -Xmx800m -XX:PermSize=128M -XX:MaxNewSize=256m
-XX:MaxPermSize=256m
2、java.lang.OutOfMemoryError: Java heap space
第一种情况是个补充,主要存在问题就是出现在这个情况中 。其默认空间(即-Xms)是物理内存的1/64 , 最大空间(-Xmx)是物理内存的1/4 。如果内存剩余不到40%,JVM就会增大堆到Xmx设置的值,内存剩余超过70%,JVM就会减小堆到Xms设置的值 。所以服务器的Xmx和Xms设置一般应该设置相同避免每次GC后都要调整虚拟机堆的大小 。假设物理内存无限大 , 那么JVM内存的最大值跟操作系统有关,一般32位机是1.5g到3g之间,而64位的就不会有限制了 。
注意:如果Xms超过了Xmx值,或者堆最大值和非堆最大值的总和超过了物理内存或者操作系统的最大限制都会引起服务器启动不起来 。
垃圾回收GC的角色
JVM调用GC的频度还是很高的,主要两种情况下进行垃圾回收:
当应用程序线程空闲;另一个是java内存堆不足时,会不断调用GC,若连续回收都解决不了内存堆不足的问题时 , 就会报out of
memory错误 。因为这个异常根据系统运行环境决定,所以无法预期它何时出现 。
根据GC的机制,程序的运行会引起系统运行环境的变化,增加GC的触发机会 。
为了避免这些问题,程序的设计和编写就应避免垃圾对象的内存占用和GC的开销 。显示调用System.GC()只能建议JVM需要在内存中对垃圾对象进行回收 , 但不是必须马上回收,
一个是并不能解决内存资源耗空的局面,另外也会增加GC的消耗 。
二、JVM内存区域组成
简单的说java中的堆和栈
java把内存分两种:一种是栈内存,另一种是堆内存
1 。在函数中定义的基本类型变量和对象的引用变量都在函数的栈内存中分配;
2 。堆内存用来存放由new创建的对象和数组
在函数(代码块)中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量所分配的内存空间;在堆中分配的内存由java虚拟机的自动垃圾回收器来管理
堆的优势是可以动态分配内存大?。?生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的 。缺点就是要在运行时动态分配内存 , 存取速度较慢;
栈的优势是存取速度比堆要快,缺点是存在栈中的数据大小与生存期必须是确定的无灵活性 。
java堆分为三个区:New、Old和Permanent
GC有两个线程:
新创建的对象被分配到New区,当该区被填满时会被GC辅助线程移到Old区,当Old区也填满了会触发GC主线程遍历堆内存里的所有对象 。Old区的大小等于Xmx减去-Xmn
java栈存放
栈调整:参数有 UseDefaultStackSize -Xss256K , 表示每个线程可申请256k的栈空间
每个线程都有他自己的Stack
三、JVM如何设置虚拟内存
提示:在JVM中如果98%的时间是用于GC且可用的Heap size 不足2%的时候将抛出此异常信息 。
提示:Heap Size 最大不要超过可用物理内存的80%,一般的要将-Xms和-Xmx选项设置为相同,而-Xmn为1/4的-Xmx值 。
提示:JVM初始分配的内存由-Xms指定 , 默认是物理内存的1/64;JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4 。
【java内存泄漏代码特征 java内存泄漏代码特征是什么】默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制 。因此服务器一般设置-Xms、-Xmx相等以避免在每次GC
后调整堆的大小 。
提示:假设物理内存无限大的话,JVM内存的最大值跟操作系统有很大的关系 。
简单的说就32位处理器虽然可控内存空间有4GB,但是具体的操作系统会给一个限制,
这个限制一般是2GB-3GB(一般来说Windows系统下为1.5G-2G,Linux系统下为2G-3G),而64bit以上的处理器就不会有限制了
提示:注意:如果Xms超过了Xmx值,或者堆最大值和非堆最大值的总和超过了物理内存或者操作系统的最大限制都会引起服务器启动不起来 。
提示:设置NewSize、MaxNewSize相等,"new"的大小最好不要大于"old"的一半,原因是old区如果不够大会频繁的触发"主" GC
,大大降低了性能
JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;
由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4 。
解决方法:手动设置Heap size
修改TOMCAT_HOME/bin/catalina.bat
在“echo "Using CATALINA_BASE: $CATALINA_BASE"”上面加入以下行:
JAVA_OPTS="-server -Xms800m -Xmx800m -XX:MaxNewSize=256m"
四、性能检查工具使用
定位内存泄漏:
JProfiler工具主要用于检查和跟踪系统(限于Java开发的)的性能 。JProfiler可以通过时时的监控系统的内存使用情况,随时监视垃圾回收,线程运行状况等手段,从而很好的监视JVM运行情况及其性能 。
1. 应用服务器内存长期不合理占用,内存经常处于高位占用,很难回收到低位;
2. 应用服务器极为不稳定,几乎每两天重新启动一次,有时甚至每天重新启动一次;
3. 应用服务器经常做Full GC(Garbage Collection),而且时间很长,大约需要30-40秒,应用服务器在做Full
GC的时候是不响应客户的交易请求的,非常影响系统性能 。
因为开发环境和产品环境会有不同,导致该问题发生有时会在产品环境中发生,通常可以使用工具跟踪系统的内存使用情况 , 在有些个别情况下或许某个时刻确实是使用了大量内存导致out
of memory,这时应继续跟踪看接下来是否会有下降,
如果一直居高不下这肯定就因为程序的原因导致内存泄漏 。
五、不健壮代码的特征及解决办法
1、尽早释放无用对象的引用 。好的办法是使用临时变量的时候,让引用变量在退出活动域后,自动设置为null,暗示垃圾收集器来收集该对象,防止发生内存泄露 。
对于仍然有指针指向的实例,jvm就不会回收该资源,因为垃圾回收会将值为null的对象作为垃圾 , 提高GC回收机制效率;
2、我们的程序里不可避免大量使用字符串处理,避免使用String,应大量使用StringBuffer,每一个String对象都得独立占用内存一块区域;
String str = "aaa";
String str2 = "bbb";
String str3 = strstr2;//假如执行此次之后str
,str2以后再不被调用,那它就会被放在内存中等待Java的gc去回收,程序内过多的出现这样的情况就会报上面的那个错误,建议在使用字符串时能使用StringBuffer就不要用String,这样可以省不少开销;
3、尽量少用静态变量,因为静态变量是全局的,GC不会回收的;
4、避免集中创建对象尤其是大对象,JVM会突然需要大量内存,这时必然会触发GC优化系统内存环境;显示的声明数组空间,而且申请数量还极大 。
这是一个案例想定供大家警戒
使用jspsmartUpload作文件上传,运行过程中经常出现java.outofMemoryError的错误,
检查之后发现问题:组件里的代码
m_totalBytes = m_request.getContentLength();
m_binArray = new byte[m_totalBytes];
问题原因是totalBytes这个变量得到的数极大,导致该数组分配了很多内存空间 , 而且该数组不能及时释放 。解决办法只能换一种更合适的办法,至少是不会引发outofMemoryError的方式解决 。参考:;id=3747
5、尽量运用对象池技术以提高系统性能;生命周期长的对象拥有生命周期短的对象时容易引发内存泄漏,例如大集合对象拥有大数据量的业务对象的时候,可以考虑分块进行处理,然后解决一块释放一块的策略 。
6、不要在经常调用的方法中创建对象,尤其是忌讳在循环中创建对象 。可以适当的使用hashtable,vector
创建一组对象容器,然后从容器中去取那些对象 , 而不用每次new之后又丢弃
7、一般都是发生在开启大型文件或跟数据库一次拿了太多的数据,造成 Out Of Memory Error
的状况,这时就大概要计算一下数据量的最大值是多少,并且设定所需最小及最大的内存空间值 。
如何识别Java中的内存泄漏一般来说内存泄漏有两种情况 。一种情况 , 在堆中java内存泄漏代码特征的分配的内存 , 在没有将其释放掉的时候,就将所有能访问这块内存的方式都删掉(如指针重新赋值);另一种情况则是在内存对象明明已经不需要的时候,还仍然保留着这块内存和它的访问方式(引用) 。第一种情况,在Java中已经由于垃圾回收机制的引入,得到java内存泄漏代码特征了很好的解决 。所以 , Java中的内存泄漏,主要指的是第二种情况 。
可能光说概念太抽象了,大家可以看一下这样的例子:
1
Vector
v=new
Vector(10);
2
for
(int
i=1;i100;
i){
3
Object
o=new
Object();
4
v.add(o);
5
o=null;
6
}
在这个例子中,代码栈中存在Vector对象的引用v和Object对象的引用o 。在For循环中,我们不断的生成新的对象,然后将其添加到Vector对象中,之后将o引用置空 。问题是当o引用被置空后 , 如果发生GC,我们创建的Object对象是否能够被GC回收呢?答案是否定的 。因为,GC在跟踪代码栈中的引用时,会发现v引用,而继续往下跟踪 , 就会发现v引用指向的内存空间中又存在指向Object对象的引用 。也就是说尽管o引用已经被置空 , 但是Object对象仍然存在其他的引用,是可以被访问到的,所以GC无法将其释放掉 。如果在此循环之后,Object对象对程序已经没有任何作用,那么我们就认为此Java程序发生了内存泄漏 。
尽管对于C/C中的内存泄露情况来说,Java内存泄露导致的破坏性小 , 除了少数情况会出现程序崩溃的情况外,大多数情况下程序仍然能正常运行 。但是,在移动设备对于内存和CPU都有较严格的限制的情况下 , Java的内存溢出会导致程序效率低下、占用大量不需要的内存等问题 。这将导致整个机器性能变差,严重的也会引起抛出OutOfMemoryError,导致程序崩溃 。
java内存泄露是什么意思?Java内存泄露\x0d\x0a一般来说内存泄漏有两种情况 。一种情况如在C/C语言中的 , 在堆中的分配的内存,在没有将其释放掉的时候,就将所有能访问这块内存的方式都删掉(如指针重新赋值);另一种情况则是在内存对象明明已经不需要的时候 , 还仍然保留着这块内存和它的访问方式(引用) 。第一种情况 , 在Java中已经由于垃圾回收机制的引入,得到了很好的解决 。所以,Java中的内存泄漏,主要指的是第二种情况 。\x0d\x0a可能光说概念太抽象了,大家可以看一下这样的例子:\x0d\x0a1Vectorv=newVector(10);\x0d\x0a2for(inti=1;i
回答于 2022-12-14
Java 程序里的内存泄漏Java 程序里java内存泄漏代码特征的内存泄漏是如何表现的大多数程序员都知道使用类似于 Java 的编程语言的好处之一就是java内存泄漏代码特征他们无需再为内存的分配和释放所担心了 java内存泄漏代码特征你只需要简单地创建对象 当它们不再为程序所需要时 Java 会自行通过一个被称为垃圾收集的机制将其移除 这个过程意味着 Java 已经解决了困扰其他编程语言的一个棘手的问题 可怕的内存泄漏 果真是这样的吗java内存泄漏代码特征?在进行深入讨论之前 让java内存泄漏代码特征我们先回顾一下垃圾收集是如何进行实际工作的 垃圾收集器的工作就是找到程序不再需要的对象并在当它们不再被访问或引用时将它们移除掉 垃圾收集器从贯穿整个程序生命周期的类这个根节点开始 扫描所有引用到的节点 在遍历节点时 它跟踪那些被活跃引用着的对象 那些不再被引用的对象就满足了垃圾回收的条件 当这些对象被移除时被它们占用的内存资源会交还给 Java 虚拟机(JVM)因此 Java 代码的确不需要程序员负责内存管理的清理工作 它自行对不再使用的对象进行垃圾收集 然而 需要记住的是 垃圾收集的关键在于一个对象在不再被引用时才被统计为不再使用 下图对这一概念进行了说明
java内存泄漏代码特征的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于java内存泄漏代码特征是什么、java内存泄漏代码特征的信息别忘了在本站进行查找喔 。
推荐阅读
- 对魔忍有动作游戏吗,对魔忍有动作游戏吗视频
- asp.net京东商城源码,京东网站源码
- fcss图标代码搜索的简单介绍
- 直播流地址工具,直播拉流地址是什么
- java代码使用js值 java执行javascript代码并获取结果
- 抖音直播为什么关同城号,抖音直播关闭同城以后为什么还推荐同城的?
- 电脑怎么制作个人信息卡,电脑怎么制作个人信息卡模板
- 阿强的选择小游戏解谜,阿强 wow
- windows系统屏幕的简单介绍