一、背景知识

1、JVM体系结构

2、JVM运行时数据区

3、JVM内存模型

JVM运行时内存 = 共享内存区 + 线程内存区

3-1、共享内存区

共享内存区 = 持久带 + 堆

持久带 = 方法区 + 其他

堆 = Old Space + Young Space

Young Space = Eden + S0 + S1

3-1-1、持久代

JVM用持久带(Permanent Space)实现方法区,主要存放所有已加载的类信息,方法信息,常量池等等。

可通过-XX:PermSize和-XX:MaxPermSize来指定持久带初始化值和最大值。

Permanent Space并不等同于方法区,只不过是Hotspot JVM用Permanent Space来实现方法区而已,有些虚拟机没

有Permanent Space而用其他机制来实现方法区。

3-1-2、堆

堆(heap),主要用来存放类的对象实例信息(包括new操作实例化的对象和定义的数组)。

堆分为Old Space(又名,Tenured Generation)和Young Space。

Old Space主要存放应用程序中生命周期长的存活对象;

Eden(伊甸园)主要存放新生的对象;

S0和S1是两个大小相同的内存区域,主要存放每次垃圾回收后Eden存活的对象,作为对象从Eden过渡到Old Space

的缓冲地带(S是指英文单词Survivor Space)。

堆之所以要划分区间,是为了方便对象创建和垃圾回收,后面垃圾回收部分会解释。

3-2、线程内存区

线程内存区=单个线程内存+单个线程内存+.......

单个线程内存=PC Regster+JVM栈+本地方法栈

JVM栈=栈帧+栈帧+.....

栈帧=局域变量区+操作数区+帧数据区

在Java中,一个线程会对应一个JVM栈(JVM Stack),JVM栈里记录了线程的运行状态。

JVM栈以栈帧为单位组成,一个栈帧代表一个方法调用。栈帧由三部分组成:局部变量区、操作数栈、帧数据区。

二、堆溢出

堆(Heap)是Java存放对象实例的地方。

堆溢出可以分为以下两种情况,这两种情况都会抛出OutOfMemoryError:java heap space异常:

1、内存泄漏

内存泄漏是指对象实例在新建和使用完毕后,仍然被引用,没能被垃圾回收释放,一直积累,直到没有剩余

内存可用。

如果内存泄露,我们要找出泄露的对象是怎么被GC ROOT引用起来,然后通过引用链来具体分析泄露的原因。

分析内存泄漏的工具有:Jprofiler,visualvm等。

示例代码:

package com.jvm;

import java.util.ArrayList;

import java.util.List;

import java.util.UUID;

/**

* 内存泄漏

* @author feizi

* @time 2015-1-23上午8:42:53

*/

public class OOMTest {

public static void main(String[] args) {

List list = new ArrayList();

while(true){

list.add(UUID.randomUUID());

}

}

}

看看控制台的输出结果,因为我这边的JVM设置的参数内存足够大,所以需要等待一定的时间,才能看到效果:

如果是用CMD命令行,就可以自己指定参数编译运行了,这样效果就更快一些:

通过下列命令运行程序,注意先要用javac命令将.java源文件编译成.class类字节码文件。

java -Xms10M -Xmx10M -XX:-UseGCOverheadLimit OOMTest

2、内存溢出

内存溢出是指当我们新建一个实力对象时,实例对象所需占用的内存空间大于堆的可用空间。

如果出现了内存溢出问题,这往往是程序本生需要的内存大于了我们给虚拟机配置的内存,这种情况下,我们可以采用调大-Xmx来解决这种问题。

示例代码:

package com.jvm;

import java.util.ArrayList;

import java.util.List;

/**

* 内存溢出

* @author feizi

* @time 2015-1-23上午8:56:22

*/

public class OOMTest_1 {

public static void main(String args[]){

List byteList = new ArrayList();

byteList.add(new byte[1000 * 1024 * 1024]);

}

}

看看控制台的运行效果:

使用CMD命令行指定参数运行:

java -verbose:gc -Xmn10M -Xms20M -Xmx20M -XX:+PrintGC OOMTest_1

三、线程栈

栈(JVM Stack)存放主要是栈帧( 局部变量表, 操作数栈 , 动态链接 , 方法出口信息 )的地方。注意区分栈和栈帧:栈里包含栈帧。

与线程栈相关的内存异常有两个:

a)、StackOverflowError(方法调用层次太深,内存不够新建栈帧)

b)、OutOfMemoryError(线程太多,内存不够新建线程)

1、java.lang.StackOverflowError

栈溢出抛出java.lang.StackOverflowError错误,出现此种情况是因为方法运行的时候,请求新建栈帧时,

栈所剩空间小于战帧所需空间。

例如,通过递归调用方法,不停的产生栈帧,一直把栈空间堆满,直到抛出异常 :

示例代码:

package com.jvm;

/**

* 栈溢出

* @author feizi

* @time 2015-1-23上午9:13:11

*/

public class SOFTest {

public void stackOverFlowMethod(){

stackOverFlowMethod();

}

/**

* 通过递归调用方法,不停的产生栈帧,一直把栈空间堆满,直到抛出异常 :

* @param args

*/

public static void main(String[] args) {

SOFTest sof = new SOFTest();

sof.stackOverFlowMethod();

}

}

看看控制台运行的效果:

作者:hu1991die 发表于2015-1-23 11:02:56 原文链接

阅读:38 评论:0 查看评论

java 溢出与泄露_Java内存溢出与栈溢出相关推荐

  1. java栈堆溢出怎么解决_java内存溢出示例(堆溢出、栈溢出)

    堆溢出:/** * @author LXA * 堆溢出 */ public class Heap { public static void main(String[] args) { ArrayLis ...

  2. java什么时候可能产生内存溢出_JAVA内存泄露和内存溢出

    1)概念: 内存溢出:指在指定大小的内存空间,写入了超出大小的数据,从而导致了内存溢出. 内存溢出:指程序运行过程中无法申请到足够的内存而导致的一种错误. 内存溢出通常发生于OLD段或Perm段垃圾回 ...

  3. Java内存泄露和内存溢出、JVM命令行工具、.JDK可视化工具、Java Class文件

    1.Java内存泄露和内存溢出对比 1.1 Java 内存泄露 内存泄露是指一个不再被程序使用的对象或变量还在内存中占用空间. 1.1.1判断内存空间是否符合垃圾回收的标准 在Java语言中,判断一个 ...

  4. Java基础恶补——内存泄露、内存溢出

     Java基础恶补--内存泄露.内存溢出 (2010-09-15 15:56:26) 转载 标签: 杂谈 要点 内存泄露是指程序中间动态分配了内存,但在程序结束时没有释放这部分内存,从而造成那部分 ...

  5. java内存泄露和内存溢出

    内存泄露 是指:对象没有被用到,但是又无法被GC回收就是内存泄露: 分类:经常发生: 发生内存泄露的代码会被多次执行,每次执行,泄露一块内存偶然发生: 在某些特定情况下才会发生一次性: 发生内存泄露的 ...

  6. java 如何排查内存溢出_java 内存溢出排查

    测试代码,如下示例: import java.util.ArrayList; import java.util.List; /** * @Description 测试内存溢出, 启动时设置参数,最大堆 ...

  7. java 队列占用内存大小_Java线程池队列吃的太饱,撑着了咋整?java 队列过大导致内存溢出...

    Java的Executors框架提供的定长线程池内部默认使用LinkedBlockingQueue作为任务的容器,这个队列是没有限定大小的,可以无限向里面submit任务. 当线程池处理的太慢的时候, ...

  8. jvm故障 内存泄露和内存溢出总结

    目录 内存泄漏memory leak 内存泄漏的分类(按发生方式来分类) 内存泄露的场景 静态集合类 / 长生命周期的对象持有短生命周期对象的引用 / 单例模式 /类加载器 各种连接,如数据库连接.网 ...

  9. Java常见的几种内存溢出及解决方法

    Java常见的几种内存溢出及解决方法[情况一]: java.lang.OutOfMemoryError:Javaheapspace:这种是java堆内存不够,一个原因是真不够(如递归的层数太多等),另 ...

最新文章

  1. Wireshark安装失败或找不到网络接口问题
  2. IAR EW6.30版本下建立STM32工程(芯片型号STM32F105VC)
  3. Dynamips和Vmware完成CCVP试验(2)
  4. React with Webpack - 2: css 处理
  5. python成员运算符包括_Python 使用成员运算符案例
  6. apipost如何设置断言
  7. 硬见小百科:尺寸公差、形位公差、表面粗糙度数值上的关系
  8. selenium模拟鼠标滑动
  9. jsonp跨域请求原理
  10. Android Killer反编译时遇到的异常
  11. MindSpore21天实战营(2):基于BERT实现中文新闻分类实战
  12. LitsModer —— 开发日志(上)
  13. 一条sql语句查出男生前5名和女生前五名
  14. 怎么把html5做成动态壁纸,在电脑上怎样把小视频做成动态壁纸
  15. TCP文件传输服务器
  16. DWH和DB以及DATA Mart区别
  17. 案例:用逻辑回归制作评分卡
  18. C++电脑程序设计语言介绍
  19. win 10 + vs2017+C++的运行环境练习的2048游戏(附源码)
  20. linux 内核态 cos函数,浅析μCOS/II v2.85内核OSMboxPend()和OSMboxPost()函数工作原理

热门文章

  1. 2.特定领域知识图谱融合方案:学以致用-问题匹配鲁棒性评测比赛验证【四】
  2. lin总线可以控制几个节点_LIN主从节点设计与实现
  3. 潍坊美丽街景智慧公厕,诠释智慧城市的公共厕所如何建设 | 中期科技ZONTREE智慧公厕@快讯
  4. 100个常见的“公共标志和说明”英文表达
  5. angular条件渲染、列表渲染、属性绑定、样式绑定、事件绑定
  6. 手动搜网模式有缺陷么?
  7. 关于写小米手机必败另一面
  8. 【bzoj 1502】月下柠檬树
  9. iPhone提取图片上文字的方法
  10. 走在同样的路上,遇见自己的风景