javagcold的简单介绍

博主:adminadmin 2022-12-21 15:09:10 60

本篇文章给大家谈谈javagcold,以及对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

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中GC是什么?为什么要有GC?

GC是垃圾回收的意思(gabage collection),内存处理器是编程人员容易出现问题的地方,忘记或者错误的内存回收导致程序或者系统的不稳定甚至崩溃,java的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,java语言没有提供释放已分配内存的俄显示操作方法。

希望能帮到你,谢谢!

java程序内存溢出一般什么原因

JVM内存设置小了 或者一次性读的数据过大 例如list vertor

一、内存溢出类型

1、java.lang.OutOfMemoryError: PermGen space

JVM管理两种类型的内存,堆和非堆。堆是给开发人员用的上面说的就是,是在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进行清理,所以如果你的应用中有很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。

默认空余堆内存小于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 = str + str2;//假如执行此次之后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服务程序是否需要设置JVM参数

兄台要的:

JVM内存参数设置

(A)

PermGen space:全称是Permanent Generation space。就是说是永久保存的区域,用于存放Class和Meta信息,Class在被Load的时候被放入该区域

Heap space:存放Instance。

(B)GC(Garbage Collection)应该不会对PermGen space进行清理

所以如果你的APP会LOAD很多CLASS的话,就很可能出现PermGen space错误

(1)Heap设定与垃圾回收Java Heap分为3个区,Young,Old和Permanent。Young保存刚实例化的对象。当该区被填满时,GC会将对象移到Old区。Permanent区则负责保存反射对象.

(2)JVM的Heap分配可以使用-X参数设定,

(9)+XX:AggressiveHeap会使得 Xms 1220m没有意义

-Xms 初始Heap大小

-Xmx java heap最大值 ,不应该超过物理内存的90%

-Xmn young generation的heap大小

(3)

JVM有2个GC线程。第一个线程负责回收Heap的Young区。第二个线程在Heap不足时,遍历Heap,将Young 区升级为Older区。Older区的大小等于-Xmx减去-Xmn,不能将-Xms的值设的过大,因为第二个线程被迫运行会降低JVM的性能。

(4)如果你发现每次GC后,Heap的剩余空间会是总空间的50%,这表示你的Heap处于健康状态。许多Server端的Java程序每次GC后最好能有65%的剩余空间

(5)Server端JVM最好将-Xms和-Xmx设为相同值。为了优化GC,最好让-Xmn值约等于-Xmx的1/3[2]。

(6)一个GUI程序最好是每10到20秒间运行一次GC,每次在半秒之内完成[2]。

(7)Stack的设定

每个线程都有他自己的Stack。

-Xss 每个线程的Stack大小,最佳值应该是128K,默认值好像是512k.

Stack的大小限制着线程的数量。如果Stack过大就好导致内存溢漏。-Xss参数决定Stack大小,例如-Xss1024K。如果Stack太小,也会导致Stack溢漏。

(8)

修改deploy/jbossweb-tomcat55.sar/service.xml

将maxThreads根据目前的访问量由默认的250降为75,并使用jboss 4默认未写在标准service.xml里面而jboss 3写入了的2个参数: maxSparseThreads=55

如何查看 java gc 类型

Java中的GC有哪几种类型?

参数

描述

UseSerialGC

虚拟机运行在Client模式的默认值,打开此开关参数后,

使用Serial+Serial Old收集器组合进行垃圾收集。

UseParNewGC

打开此开关参数后,使用ParNew+Serial Old收集器组合进行垃圾收集。

UseConcMarkSweepGC

打开此开关参数后,使用ParNew+CMS+Serial Old收集器组合进行垃圾收集。Serial Old作为CMS收集器出现Concurrent Mode Failure的备用垃圾收集器。

UseParallelGC

虚拟机运行在Server模式的默认值,打开此开关参数后,使用Parallel Scavenge+Serial Old收集器组合进行垃圾收集。

UseParallelOldGC

打开此开关参数后,使用Parallel Scavenge+Parallel Old收集器组合进行垃圾收集。

在Java程序启动完成后,通过jps观察进程来查询到当前运行的java进程,使用

jinfo –flag UseSerialGC 进程

的方式可以定位其使用的gc策略,因为这些参数都是boolean型的常量,如果使用该种gc策略会出现+号,否则-号。

使用-XX:+上述GC策略可以开启对应的GC策略。

GC日志查看

可以通过在java命令种加入参数来指定对应的gc类型,打印gc日志信息并输出至文件等策略。

GC的日志是以替换的方式()写入的,而不是追加(),如果下次写入到同一个文件中的话,以前的GC内容会被清空。

对应的参数列表

-XX:+PrintGC 输出GC日志

-XX:+PrintGCDetails 输出GC的详细日志

-XX:+PrintGCTimeStamps 输出GC的时间戳(以基准时间的形式)

-XX:+PrintGCDateStamps 输出GC的时间戳(以日期的形式,如 2013-05-04T21:53:59.234+0800)

-XX:+PrintHeapAtGC 在进行GC的前后打印出堆的信息

-Xloggc:../logs/gc.log 日志文件的输出路径

这里使用如下的参数来进行日志的打印:

-XX:+PrintGCDateStamps -XX:+PrintGCDetails -Xloggc:./gclogs

对于新生代回收的一行日志,其基本内容如下:

2014-07-18T16:02:17.606+0800: 611.633: [GC 611.633: [DefNew: 843458K-2K(948864K), 0.0059180 secs] 2186589K-1343132K(3057292K), 0.0059490 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

其含义大概如下:

2014-07-18T16:02:17.606+0800(当前时间戳): 611.633(时间戳): [GC(表示Young GC) 611.633: [DefNew(单线程Serial年轻代GC): 843458K(年轻代垃圾回收前的大小)-2K(年轻代回收后的大小)(948864K(年轻代总大小)), 0.0059180 secs(本次回收的时间)] 2186589K(整个堆回收前的大小)-1343132K(整个堆回收后的大小)(3057292K(堆总大小)), 0.0059490 secs(回收时间)] [Times: user=0.00(用户耗时) sys=0.00(系统耗时), real=0.00 secs(实际耗时)]

老年代回收的日志如下:

2014-07-18T16:19:16.794+0800: 1630.821: [GC 1630.821: [DefNew: 1005567K-111679K(1005568K), 0.9152360 secs]1631.736: [Tenured:

2573912K-1340650K(2574068K), 1.8511050 secs] 3122548K-1340650K(3579636K), [Perm : 17882K-17882K(21248K)], 2.7854350 secs] [Times: user=2.57 sys=0.22, real=2.79 secs]

gc日志中的最后貌似是系统运行完成前的快照:

Heap

def new generation total 1005568K, used 111158K [0x00000006fae00000, 0x000000073f110000, 0x0000000750350000)

eden space 893888K, 12% used [0x00000006fae00000, 0x0000000701710e90, 0x00000007316f0000)

from space 111680K, 3% used [0x0000000738400000, 0x000000073877c9b0, 0x000000073f110000)

to space 111680K, 0% used [0x00000007316f0000, 0x00000007316f0000, 0x0000000738400000)

tenured generation total 2234420K, used 1347671K [0x0000000750350000, 0x00000007d895d000, 0x00000007fae00000)

the space 2234420K, 60% used [0x0000000750350000, 0x00000007a2765cb8, 0x00000007a2765e00, 0x00000007d895d000)

compacting perm gen total 21248K, used 17994K [0x00000007fae00000, 0x00000007fc2c0000, 0x0000000800000000)

the space 21248K, 84% used [0x00000007fae00000, 0x00000007fbf92a50, 0x00000007fbf92c00, 0x00000007fc2c0000)

No shared spaces configured.

GC日志的离线分析

可以使用一些离线的工具来对GC日志进行分析,比如sun的gchisto( ),gcviewer( ),这些都是开源的工具,用户可以直接通过版本控制工具下载其源码,进行离线分析。

下面就已gcviewer为例,简要分析一下gc日志的离线分析,gcviewer源代码工程是maven结构的,可以直接用maven进行package,这里编译的是1.34版本,本版本的快照已经上传至附件中。

需要说明的是,gcviewer支持多种参数生成的gc日志,直接通过java –jar的方式运行,加载生成的gc日志即可:

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

The End

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