1,Java内存溢出包括:堆内存溢出和栈内存溢出
首先说下:内存溢出和内存泄露
内存溢出:out of memory 是指程序申请内存时没有足够的空间了
内存泄露: memroy leak,是指程序申请内存后,无法释放已申请的内存空间。
内存泄露-》内存溢出
堆内存溢出:
排查方法:mat(memory analyzer tool)
-vmargs:后面跟VM参数
-XX:PermSize = 40M 非堆内存
-XX:HeapDumpOnOutOfMemoryError :让虚拟机出现内存溢出时dump出此时的堆内存转储快照。
-XX:HeapDumpOnCtrBreak
-xss 设置栈内存
获取转存储文件的方法:
1.任务管理器
2.jvisiualVM工具
3.jmp,jconsole工具
mat 查看内存使用情况
(1)整体内存的消耗情况(overview)
(2)分析可以对象
优化从两个层面上来优化:
(2)代码层面
内存溢出的几种方式:
一. java堆溢出
创建对象没有及时回收,
3. 如果是内存泄露,进一步通过MAT工具分析泄露对象到GC Roots的引用链。找到泄露对象是通过怎样的路径与GC Roots相关联并导致垃圾收集器无法自动回收的。 4. 如果不存在泄露,那么就是内存中得对象却是都还必须活着,就应当检查虚拟机的堆参数(-Xmx与-Xms),与机器物理内存对比看是否可以调大
二. 虚拟机和本地方法栈溢出
在单线程下,无论是由于栈帧太小还是虚拟机栈容量太小,当内存无法分配的时候,虚拟机抛出的都是StackOverflowError异常。 在多线程下,通过不断的建立线程的方式可以产生内存溢出OutOfMemoryError异常。
如果建立过多线程导致的内存溢出,在不能减少线程数或者更换64位虚拟机的情况下,就只能通过减少最大堆或者减少栈容量来获取更多的线程。
出现StackOverflowError的时候有错误堆栈可以读,即时加入+HeapDumpOnOutOfMemoryError也不会dump异常堆内存。
如果要项运行时常量池中添加内容,最简单的方法就是使用String.intern()这个Native方法。
异常信息:
四. 方法区溢出
方法区用于存放Class的相关信息,如类名、访问修饰符、常量池、字段描述、方法描述等。当大量的类产生时填满方法区,会造成方法去溢出。
方法区溢出也是一种常见内存溢出异常,一个类如果要被垃圾收集器回收,判断条件非常苛刻。