浅谈java内存管理与内存溢出异常

 更新时间:2017年10月18日 09:21:40   作者:Wilange  
下面小编就为大家带来一篇浅谈java内存管理与内存溢出异常。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

说到内存管理,笔者这里想先比较一下java与C、C++之间的区别:

在C、C++中,内存管理是由程序员负责的,也就是说程序员既要完成繁重的代码编写工作又要时常考虑到系统内存的维护

在java中,程序员无需考虑内存的控制和维护,而是交由JVM自动管理,这样就不容易出现内存泄漏和溢出的问题。然而,一旦出现内存泄漏和溢出方面的问题,如果不了解JVM的内存管理机制就很难找到错误所在。

1.JVM运行时数据区

JVM在运行java程序的时候会将它所管理的内存划分为若干个不同的区域,这些区域不仅有自己的用途,还有创建和销毁的时间。一般来说包含以下几个运行时数据区:

其中的橙色区域是各个线程私有的,即每个线程都会有自己的一份,而绿色区域是各个线程共享的。

2.java对象的创建

类加载检查

当JVM扫描到new关键字时,首先会去检查这个指令的参数是否能够在常量池中定位到一个类的符号引用,并且检查这个类的符号引用代表的类是否已被加载、解析和初始化过。如果没有,就必须先执行相应的类加载过程。

内存分配

当类加载检查通过后,JVM需要为新生对象分配内存,即是把一块确定大小的内存从java堆中划分出来。常用的划分方法有两种:指针碰撞(要求堆内存绝对规整)、空闲列表(堆内存并不规整)。

内存初始化

JVM需要将分配到的内存空间都初始化为零值(不包括对象头),这就保证了对象的实例字段在java代码中可以不赋初始值就直接使用,也就是说程序能够访问到这些字段的数据类型所对应的零值。

对象初始化

执行<init>方法,将对象按照程序员的意愿进行初始化。

3.对象的访问定位

对象创建好了,我们还希望能够快速的访问到这些对象,这就需要JVM栈上的reference(引用)数据来找到堆中的具体对象,而目前使用最多的访问方式有“句柄方式”和“直接指针”两种。

使用句柄方式访问的话,就需要在堆中划分一部分内存来作为句柄池,reference变量中存储的就是对象的句柄地址,而句柄中包含了对象实例数据和类型数据各自的具体地址信息。

使用直接指针访问的话,reference变量中存储的直接就是对象地址,但是需要考虑如何放置类型数据的相关信息。

4.内存溢出异常

JVM运行时数据区除了PC寄存器之外,其他的内存区域都有可能发生内存溢出的异常情况。PC寄存器是唯一一个在JVM规范中没有规定任何OutOfMemoryError(OOM)情况的区域

堆溢出

java中的堆用于存储对象实例,如果不断地创建对象,并且保证GC Roots到对象之间有可达路径以避免GC的回收处理,那么在对象的数量达到最大堆的容量限制后就会发生堆溢出的异常情况。

栈溢出(包括JVM栈和本地方法栈)

1.如果线程请求的栈深度大于JVM所允许的最大深度,将抛出StackOverflowError异常;

2.如果JVM在扩展栈时无法申请到足够的内存空间,将抛出OutOfMemoryError异常。

此外,还有方法区溢出、常量池溢出、本机内存溢出等等。

以上这篇浅谈java内存管理与内存溢出异常就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • ShardingSphere数据库读写分离算法及测试示例详解

    ShardingSphere数据库读写分离算法及测试示例详解

    这篇文章主要为大家介绍了ShardingSphere数据库读写分离算法及测试示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03
  • htmlcleaner使用方法及xpath语法初探

    htmlcleaner使用方法及xpath语法初探

    HtmlCleaner是一个开源的Java语言的Html文档解析器。HtmlCleaner能够重新整理HTML文档的每个元素并生成结构良好(Well-Formed)的 HTML 文档
    2015-08-08
  • Kafka日志清理实现详细过程讲解

    Kafka日志清理实现详细过程讲解

    这篇文章主要为大家介绍了Kafka日志清理实现详细过程讲解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-05-05
  • 深入了解Java中的static关键字

    深入了解Java中的static关键字

    这篇文章主要为大家详细介绍了Java中的static关键字的用法的相关资料,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的小伙伴可以学习一下
    2022-11-11
  • Java try-with-resource语法使用解析

    Java try-with-resource语法使用解析

    这篇文章主要介绍了Java try-with-resource语法使用解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • 使用@Valid+BindingResult进行controller参数校验方式

    使用@Valid+BindingResult进行controller参数校验方式

    这篇文章主要介绍了使用@Valid+BindingResult进行controller参数校验方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • 详解spring面向切面aop拦截器

    详解spring面向切面aop拦截器

    spring中有很多概念和名词,比如过滤器、拦截器、aop等。这篇文章主要介绍了详解spring面向切面aop拦截器,有兴趣的可以了解一下。
    2017-03-03
  • 一文教你如何更改IDEA已有项目的路径/名称

    一文教你如何更改IDEA已有项目的路径/名称

    由于IDEA项目路径中有中文、空格等特殊符号,影响正常使用,想要修改路径名称,怎么正确修改IDEA项目名称,使其正常运行呢?所以本文小编讲给大家详细的介绍了更改IDEA已有项目的路径/名称解决方案,需要的朋友可以参考下
    2023-11-11
  • JavaScript中new运算符的实现过程解析

    JavaScript中new运算符的实现过程解析

    这篇文章主要介绍了JavaScript中new运算符的实现过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-10-10
  • MyBatis实现Mysql数据库分库分表操作和总结(推荐)

    MyBatis实现Mysql数据库分库分表操作和总结(推荐)

    这篇文章主要介绍了MyBatis实现Mysql数据库分库分表操作和总结,需要的朋友可以参考下
    2017-08-08

最新评论