「java持久代」java持久代满

博主:adminadmin 2022-12-12 07:15:06 69

今天给各位分享java持久代的知识,其中也会对java持久代满进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

本文目录一览:

如何定位java内存泄露

1、为什么会发生内存泄漏

Java如何检测内在泄漏呢?我们需要一些工具进行检测,并发现内存泄漏问题,不然很容易发生down机问题。

编写java程序最为方便的地方就是我们不需要管理内存的分配和释放,一切由jvm来进行处理,当java对象不再被应用时,等到堆内存不够用时,jvm会进行垃圾回收,清除这些对象占用的堆内存空间,如果对象一直被应用,jvm无法对其进行回收,创建新的对象时,无法从Heap中获取足够的内存分配给对象,这时候就会导致内存溢出。而出现内存泄露的地方,一般是不断的往容器中存放对象,而容器没有相应的大小限制或清除机制。容易导致内存溢出。

当服务器应用占用了过多内存的时候,如何快速定位问题呢?现在,Eclipse MAT的出现使这个问题变得非常简单。EclipseMAT是著名的SAP公司贡献的一个工具,可以在Eclipse网站下载到它,完全免费的。

要定位问题,首先你需要获取服务器jvm某刻内存快照。jdk自带的jmap可以获取内存某一时刻的快照,导出为dmp文件后,就可以用Eclipse MAT来分析了,找出是那个对象使用内存过多。

2、内存泄漏的现象:

常常地,程序内存泄漏的最初迹象发生在出错之后,在你的程序中得到一个OutOfMemoryError。这种典型的情况发生在产品环境中,而在那里,你希望内存泄漏尽可能的少,调试的可能性也达到最小。也许你的测试环境和产品的系统环境不尽相同,导致泄露的只会在产品中暴露。这种情况下,你需要一个低负荷的工具来监听和寻找内存泄漏。同时,你还需要把这个工具同你的系统联系起来,而不需要重新启动他或者机械化你的代码。也许更重要的是,当你做分析的时候,你需要能够同工具分离而使得系统不会受到干扰。

一个OutOfMemoryError常常是内存泄漏的一个标志,有可能应用程序的确用了太多的内存;这个时候,你既不能增加JVM的堆的数量,也不能改变你的程序而使得他减少内存使用。但是,在大多数情况下,一个OutOfMemoryError是内存泄漏的标志。一个解决办法就是继续监听GC的活动,看看随时间的流逝,内存使用量是否会增加,如果有,程序中一定存在内存泄漏。

3、发现内存泄漏

1. jstat -gc pid

可以显示gc的信息,查看gc的次数,及时间。

其中最后五项,分别是young gc的次数,young gc的时间,full gc的次数,full gc的时间,gc的总时间。

2.jstat -gccapacity pid

可以显示,VM内存中三代(young,old,perm)对象的使用和占用大小,

如:PGCMN显示的是最小perm的内存使用量,PGCMX显示的是perm的内存最大使用量,

PGC是当前新生成的perm内存占用量,PC是但前perm内存占用量。

其他的可以根据这个类推,OC是old内纯的占用量。

3.jstat -gcutil pid

统计gc信息统计。

4.jstat -gcnew pid

年轻代对象的信息。

5.jstat -gcnewcapacity pid

年轻代对象的信息及其占用量。

6.jstat -gcold pid

old代对象的信息。

7.stat -gcoldcapacity pid

old代对象的信息及其占用量。

8.jstat -gcpermcapacity pid

perm对象的信息及其占用量。

9.jstat -class pid

显示加载class的数量,及所占空间等信息。

10.jstat -compiler pid

显示VM实时编译的数量等信息。

11.stat -printcompilation pid

当前VM执行的信息。

一些术语的中文解释:

S0C:年轻代中第一个survivor(幸存区)的容量(字节)

S1C:年轻代中第二个survivor(幸存区)的容量(字节)

S0U:年轻代中第一个survivor(幸存区)目前已使用空间(字节)

S1U:年轻代中第二个survivor(幸存区)目前已使用空间(字节)

EC:年轻代中Eden(伊甸园)的容量(字节)

EU:年轻代中Eden(伊甸园)目前已使用空间(字节)

OC:Old代的容量(字节)

OU:Old代目前已使用空间(字节)

PC:Perm(持久代)的容量(字节)

PU:Perm(持久代)目前已使用空间(字节)

YGC:从应用程序启动到采样时年轻代中gc次数

YGCT:从应用程序启动到采样时年轻代中gc所用时间(s)

FGC:从应用程序启动到采样时old代(全gc)gc次数

FGCT:从应用程序启动到采样时old代(全gc)gc所用时间(s)

GCT:从应用程序启动到采样时gc用的总时间(s)

NGCMN:年轻代(young)中初始化(最小)的大小(字节)

NGCMX:年轻代(young)的最大容量(字节)

NGC:年轻代(young)中当前的容量(字节)

OGCMN:old代中初始化(最小)的大小(字节)

OGCMX:old代的最大容量(字节)

OGC:old代当前新生成的容量(字节)

PGCMN:perm代中初始化(最小)的大小(字节)

PGCMX:perm代的最大容量(字节)

PGC:perm代当前新生成的容量(字节)

S0:年轻代中第一个survivor(幸存区)已使用的占当前容量百分比

S1:年轻代中第二个survivor(幸存区)已使用的占当前容量百分比

E:年轻代中Eden(伊甸园)已使用的占当前容量百分比

O:old代已使用的占当前容量百分比

P:perm代已使用的占当前容量百分比

S0CMX:年轻代中第一个survivor(幸存区)的最大容量(字节)

S1CMX:年轻代中第二个survivor(幸存区)的最大容量(字节)

ECMX:年轻代中Eden(伊甸园)的最大容量(字节)

DSS:当前需要survivor(幸存区)的容量(字节)(Eden区已满)

TT:持有次数限制

MTT:最大持有次数限制

如果定位内存泄漏问题我一般使用如下命令:

Jstat -gcutil15469 2500 70

[root@ssss logs]# jstat -gcutil 15469 1000 300

S0 S1 E O P YGC YGCT FGC FGCT GCT

0.00 1.46 26.54 4.61 30.14 35 0.872 0 0.000 0.872

0.00 1.46 46.54 4.61 30.14 35 0.872 0 0.000 0.872

0.00 1.46 47.04 4.61 30.14 35 0.872 0 0.000 0.872

0.00 1.46 65.19 4.61 30.14 35 0.872 0 0.000 0.872

0.00 1.46 67.54 4.61 30.14 35 0.872 0 0.000 0.872

0.00 1.46 87.54 4.61 30.14 35 0.872 0 0.000 0.872

0.00 1.46 88.03 4.61 30.14 35 0.872 0 0.000 0.872

1.48 0.00 5.56 4.62 30.14 36 0.874 0 0.000 0.874

1000 代表多久间隔显示一次,

100 代表显示一次。

S0 — Heap上的 Survivor space 0 区已使用空间的百分比

S1 — Heap上的 Survivor space 1 区已使用空间的百分比

E — Heap上的 Eden space 区已使用空间的百分比

O — Heap上的 Old space 区已使用空间的百分比

P — Perm space 区已使用空间的百分比

YGC — 从应用程序启动到采样时发生 Young GC 的次数

YGCT– 从应用程序启动到采样时 Young GC 所用的时间(单位秒)

FGC — 从应用程序启动到采样时发生 Full GC 的次数

FGCT– 从应用程序启动到采样时 Full GC 所用的时间(单位秒)

GCT — 从应用程序启动到采样时用于垃圾回收的总时间(单位秒)

如果有大量的FGC就要查询是否有内存泄漏的问题了,图中的FGC数量就比较大,并且执行时间较长,这样就会导致系统的响应时间较长,如果对jvm的内存设置较大,那么执行一次FGC的时间可能会更长。

如果为了更好的证明FGC对服务器性能的影响,我们可以使用java visualVM来查看一下:

从上图可以发现执行FGC的情况,下午3:10分之前是没有FGC的,之后出现大量的FGC。

上图是jvm堆内存的使用情况,下午3:10分之前的内存回收还是比较合理,但是之后大量内存无法回收,最后导致内存越来越少,导致大量的full gc。

下面我们在看看大量full GC对服务器性能的影响,下面是我用loadrunner对我们项目进行压力测试相应时间的截图:

从图中可以发现有,在进行full GC后系统的相应时间有了明显的增加,点击率和吞吐量也有了明显的下降。所以java内存泄漏对系统性能的影响是不可忽视的。

3、定位内存泄漏

当然通过上面几种方法我们可以发现java的内存泄漏问题,但是作为一名合格的高级工程师,肯定不甘心就把这样的结论交给开发,当然这也的结论交给开发,开发也很难定位问题,为了更好的提供自己在公司的地位,我们必须给开发工程师提供更深入的测试结论,下面就来认识一下MemoryAnalyzer.exe。java内存泄漏检查工具利器。

首先我们必须对jvm的堆内存进行dump,只有拿到这个文件我们才能分析出jvm堆内存中到底存了些什么内容,到底在做什么?

MemoryAnalyzer的用户我在这里就不一一说明了,我的博客里也有说明,下面就展示我测试的成功图:

其中深蓝色的部分就为内存泄漏的部分,java的堆内存一共只有481.5M而内存泄漏的部分独自占有了336.2M所以本次的内存泄漏很明显,那么我就来看看那个方法导致的内存泄漏:

从上图我们可以发现红线圈着的方法占用了堆内存的67.75%,如果能把这个测试结果交给开发,开发是不是应该很好定位呢。所以作为一名高级测试工程师,我们需要学习的东西太多。

虽然不确定一定是内存泄漏,但是可以准确的告诉开发问题出现的原因,有一定的说服力。

java中什么是持久层

持久层,又叫数据访问层。是和数据库直接打交道的层。

所有增删改查的操作全在这个层里

如何检查和解决java虚拟机内存溢出的问题

一,jvm内存区域

1, 程序计数器

一块很小的内存空间,作用是当前线程所执行的字节码的行号指示器。

2, java栈

与程序计数器一样,java栈(虚拟机栈)也是线程私有的,其生命周期与线程相同。通常存放基本数据类型,对象引用(一个指向对象起始地址的引用指针或一个代表对象的句柄),reeturnAddress类型(指向一条字节码指令的地址)

栈区域有两种异常类型:如果线程请求的栈深度大于虚拟机所允许的深度,将抛StrackOverflowError异常;如果虚拟机栈可以动态扩展(大部分虚拟机都可动态扩展),当扩展时无法申请到足够的内存时会抛出OutOfMemoryError异常。

3, 本地方法栈

与虚拟机栈作用很相似,区别是虚拟机栈为虚拟机执行java方法服务,而本地方法栈则是为虚拟机用到的Native方法服务。和虚拟机栈一样可能抛出StackOverflowError和OutOfMemoryError异常。

4, java堆

java

Heap是jvm所管理的内存中最大的区域。JavaHeap是被所有线程共享的一块内存区域,在虚拟机启动时创建。主要存放对象实例。JavaHeap

是垃圾收集器管理的主要区域,其可细分为新生代和老年代。如果在堆中没有内存完成实例分配,并且也无法再扩展时,会抛出OutOfMemoryError

异常。

5, 方法区

与javaHeap一样是各个线程共享的内存区域,用于存放已被虚拟机加载的类信息、常量、静态变量、及时编译器编译后的代码等数据。当方法区无法满足内

存分配的需求时,将抛出OutOfMemoryError异常。方法同时包含常听说的运行时常量池,用于存放编译期生成的各种字面量和符号引用。

6, 直接内存

直接内存并不是虚拟机运行时数据区的一部分,也不是java虚拟机规范中定义的内存区域,是jvm外部的内存区域,这部分区域也可能导致OutOfMemoryError异常。

二,jvm参数

-Xss(StackSpace)栈空间

-Xms ,-Xmx(heap memory

space)堆空间:Heap是大家最为熟悉的区域,他是jvm用来存储对象实例的区域,Heap在32位的系统中最大为2G,其大小通过-Xms和

-Xmx来控制,-Xms为jvm启动时申请的最小Heap内存,默认为物理内存的1/64,但小于1G,-Xmx为jvm可申请的最大的Heap内存,

默认为物理内存的1/4,一般也小于1G,默认当空余堆内存小于40%时,jvm会最大Heap的大小到-Xmx指定大小,可通过

-XX:MinHeapFreeRatio来指定这个比例,当空余堆内存大于70%时,JVM会将Heap的大小往-Xms指定的大小调整,可通过

-XX:MaxHeapFreeRatio来指定这个比例,但通常为了避免频繁调整HeapSize的大小,将-Xms和-Xmx的值设为相同。

-XX:PermSize -XX:MaxPermSize :方法区持久代大小: 方法区域也是全局共享的,在一定的条件下它也会被 GC ,当方法区域需要使用的内存超过其允许的大小时,会抛出 OutOfMemory 的错误信息。

三,常见内存溢出错误解决办法

1, OutOfMemoryError异常

除了程序计数器外,虚拟机内存的其他几个运行时区域都有发生OutOfMemoryError(OOM)异常的可能,

Java Heap 溢出

一般的异常信息:java.lang.OutOfMemoryError:Java heap spacess

java堆用于存储对象实例,我们只要不断的创建对象,并且保证GC Roots到对象之间有可达路径来避免垃圾回收机制清除这些对象,就会在对象数量达到最大堆容量限制后产生内存溢出异常。

出现这种异常,一般手段是先通过内存映像分析工具(如Eclipse Memory

Analyzer)对dump出来的堆转存快照进行分析,重点是确认内存中的对象是否是必要的,先分清是因为内存泄漏(Memory

Leak)还是内存溢出(Memory Overflow)。

如果是内存泄漏,可进一步通过工具查看泄漏对象到GC Roots的引用链。于是就能找到泄漏对象时通过怎样的路径与GC Roots相关联并导致垃圾收集器无法自动回收。

如果不存在泄漏,那就应该检查虚拟机的参数(-Xmx与-Xms)的设置是否适当。

2, 虚拟机栈和本地方法栈溢出

如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError异常。

如果虚拟机在扩展栈时无法申请到足够的内存空间,则抛出OutOfMemoryError异常

这里需要注意当栈的大小越大可分配的线程数就越少。

3, 运行时常量池溢出

异常信息:java.lang.OutOfMemoryError:PermGen space

如果要向运行时常量池中添加内容,最简单的做法就是使用String.intern()这个Native方法。该方法的作用是:如果池中已经包含一个等于

此String的字符串,则返回代表池中这个字符串的String对象;否则,将此String对象包含的字符串添加到常量池中,并且返回此String

对象的引用。由于常量池分配在方法区内,我们可以通过-XX:PermSize和-XX:MaxPermSize限制方法区的大小,从而间接限制其中常量

池的容量。

4, 方法区溢出

方法区用于存放Class的相关信息,如类名、访问修饰符、常量池、字段描述、方法描述等。

异常信息:java.lang.OutOfMemoryError:PermGen space

方法区溢出也是一种常见的内存溢出异常,一个类如果要被垃圾收集器回收,判定条件是很苛刻的。在经常动态生成大量Class的应用中,要特别注意这点。

Java JVM怎么学习啊?从哪方面入手

Java JVM如何学习?首先要了解他的类型!

java虚拟机学习

数据类型(基本类型、引用类型)====数值本身、引用值 2. 堆、栈=====栈是运行时的单位(如何处理数据),堆是存储的单位(数据如何存储)

------栈因为是运行单位,因此里面存储的信息都是跟当前线程(或程序相关信息的。包括局部变量、程序运行状态、方法返回值等等;而堆只负责存储对象信息。在Java中,Main函数就是栈的起始点,也是程序的起始点。堆中存的是对象,栈中存的是基本数据类型和堆中对象的引用

Java中的参数传递时传值呢?还是传引用?

a) 程序运行永远都是在栈中进行的,因而参数传递时,只存在传递基本类型和对象引

用的问题。不会直接传对象本身。

b) Java在方法调用传递参数时,因为没有指针,所以它都是进行传值调用

c) 堆和栈中,栈是程序运行最根本的东西。程序运行可以没有堆,但是不能没有栈。

而堆是为栈进行数据存储服务,说白了堆就是一块共享的内存。不过,正是因为堆和栈的分离的思想,才使得Java的垃圾回收成为可能

Java对象的大小

a) 一个空Object对象的大小是8byte(没有任何属性的对象) b) Object ob = new Object();所占的空间为:4byte+8byte。4byte是上面部分所说的Java

栈中保存引用的所需要的空间。而那8byte则是Java堆中对象的信息.不论什么样的Java对象,其大小都必须是大于8byte

c) Java在对对象内存分配时都是以8的整数倍来分,基本类型包装类的大小至少是

16byte

引用类型

a) 对象引用类型分为强引用、软引用、弱引用和虚引用。

b) 强引用:就是我们一般声明对象是时虚拟机生成的引用,强引用环境下,垃圾回收

时需要严格判断当前对象是否被强引用,如果被强引用,则不会被垃圾回收 c) 软引用:软引用一般被作为缓存来使用。与强引用的区别是,软引用在垃圾回收时,

虚拟机会根据当前系统的剩余内存来决定是否对软引用进行回收。如果剩余内存比较紧张,则虚拟机会回收软引用所引用的空间;如果剩余内存相对富裕,则不会进行回收。换句话说,虚拟机在发生OutOfMemory时,肯定是没有软引用存在的。 d) 弱引用:弱引用与软引用类似,都是作为缓存来使用。但与软引用不同,弱引用在

进行垃圾回收时,是一定会被回收掉的,因此其生命周期只存在于一个垃圾回收周期内。

JVM调优总结(三)-基本垃圾回收算法 7. 垃圾回收面临的问题

a) 如何区分垃圾。垃圾回收的起点是一些根对象(java栈, 静态变量, 寄存器...)。而

最简单的Java栈就是Java程序执行的main函数 b) 如何处理碎片。“复制”方式和“标记-整理”方式,都可以解决碎片的问题。 c) 如何解决同时存在的对象创建和对象回收问题;在现有的垃圾回收方式中,要进行

垃圾回收前,一般都需要暂停整个应用(即:暂停内存的分配),然后进行垃圾回收,回收完成后再继续应用

8. 分代垃圾回收详述

a) 为什么要分代:不同的对象的生命周期是不一样的。因此,不同生命周期的对象可

以采取不同的收集方式,以便提高回收效率。

b) 如何分代虚拟机中的共划分为三个代:年轻代(Young Generation)、年老点(OldGeneration)和持久代(Permanent Generation)。其中持久代主要存放的是Java类的类信息,与垃圾收集要收集的Java对象关系不大。年轻代和年老代的划分是对垃圾收集影响比较大的

什么情况下触发垃圾回收GC有两种类型:Scavenge GC(当新对象生成,并且在Eden

申请空间失败时,就会触发Scavenge GC,对Eden区域进行GC,清除非存活对象,并且把尚且存活的对象移动到Survivor区)和Full GC(对整个堆进行回收)

典型配置举例

a) 堆大小设置

b) 回收器选择。串行收集器、并行收集器、并发收集器,但是串行收集器只适用于小

数据量的情况,所以这里的选择主要针对并行收集器和并发收集器。

垃圾回收的瓶颈

a) 传统分代垃圾回收方式,已经在一定程度上把垃圾回收给应用带来的负担降到了最

小,把应用的吞吐量推到了一个极限。但是他无法解决的一个问题,就是Full GC所带来的应用暂停

学习java的伙伴加我的 群去下载视频资料 540-998-279!

java持久代的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于java持久代满、java持久代的信息别忘了在本站进行查找喔。

The End

发布于:2022-12-12,除非注明,否则均为首码项目网原创文章,转载请注明出处。