首页 > 系统相关 >java内存管理

java内存管理

时间:2023-01-03 10:32:38浏览次数:66  
标签:Java 管理 对象 线程 内存 java 方法 分配


1. java是如何管理内存的
 Java的内存管理就是对象的分配和释放问题。(两部分) 
分配 :内存的分配是由程序完成的,程序员需要通过关键字new 为每个对象申请内存空间 (基本类型除外),所有的对象都在堆 (Heap)中分配空间。
释放 :对象的释放是由垃圾回收机制决定和执行的,这样做确实简化了程序员的工作。但同时,它也加重了JVM的工作。因为,GC为了能够正确释放对象,GC必须监控每一个对象的运行状态,包括对象的申请、引用、被引用、赋值等,GC都需要进行监控。 

2. 什么叫java的内存泄露
     在Java中,内存泄漏就是存在一些被分配的对象,这些对象有下面两个特点,首先,这些对象是可达的,即在有向图中,存在通路可以与其相连(也就是说仍存在该内存对象的引用);其次,这些对象是无用的,即程序以后不会再使用这些对象。如果对象满足这两个条件,这些对象就可以判定为Java中的内存泄漏,这些对象不会被GC所回收,然而它却占用内存。

3. JVM的内存区域组成

java把内存分两种:一种是栈内存,另一种是堆内存。在函数中定义的基本类型变量和对象的引用变量都在函数的栈内存中分配;堆内存用来存放由new创建的对象和数组以及对象的实例变量 在函数(代码块)中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量所分配的内存空间;在堆中分配的内存由java虚拟机的自动垃圾回收器来管理



java文件加载的流程图:

java内存管理_JVM


java内存管理_内存_02

栈:

与程序计数器一样,Java虚拟机栈(Java Virtual Machine Stacks)也是线程私有的,它的生命周期与线程相同。
方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧(Stack Frame)用于存储局部变量表、操作栈、动态链接、方法出口等信息。每一个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。

1)栈与线程
 
JVM是基于栈的虚拟机.JVM为每个新创建的线程都分配一个栈.也就是说,对于一个Java程序来说,它的运行就是通过对栈的操作来完成的。栈以帧为单位保存线程的状态。JVM对栈只进行两种操作:以帧为单位的压栈和出栈操作。
我们知道,某个线程正在执行的方法称为此线程的当前方法.我们可能不知道,当前方法使用的帧称为当前帧。当线程激活一个Java方法,JVM就会在线程的 Java堆栈里新压入一个帧。这个帧自然成为了当前帧.在此方法执行期间,这个帧将用来保存参数,局部变量,中间计算过程和其他数据.这个帧在这里和编译原理中的活动纪录的概念是差不多的.
从Java的这种分配机制来看,堆栈又可以这样理解:栈(Stack)是操作系统在建立某个进程时或者线程(在支持多线程的操作系统中是线程)为这个线程建立的存储区域,该区域具有先进后出的特性。

2)栈中的方法调用

嵌套方法的出栈和入栈示意图:

java内存管理_JVM_03

上图中描述了嵌套方法时,stack的内存分配图,由上面可以知道,当嵌套方法调用时,嵌套越深,stack的内存就越晚才能释放,因此,在实际开发过程中,不推荐大家使用递归来进行方法的调用,递归很容易导致stack flow。

非嵌套方法的出栈入栈过程:

java内存管理_Java_04

堆:

每一个Java应用都唯一对应一个JVM实例,每一个实例唯一对应一个堆。应用程序在运行中所创建的所有类实例或数组都放在这个堆中,并由应用所有的线程共享.跟C/C++不同,Java中分配堆内存是自动初始化的。Java中所有对象的存储空间都是在堆中分配的,但是这个对象的引用却是在堆栈中分配,也就是说在建立一个对象时从两个地方都分配内存,在堆中分配的内存实际建立这个对象,而在堆栈中分配的内存只是一个指向这个堆对象的指针(引用)而已。


Java堆是垃圾收集器管理的主要区域,因此很多时候也被称做“GC堆”(Garbage Collected Heap,幸好国内没翻译成“垃圾堆”)。如果从内存回收的角度看,由于现在收集器基本都是采用的分代收集算法,所以Java堆中还可以细分为:新生代和老年代;再细致一点的有Eden空间、From Survivor空间、To Survivor空间等。


堆和栈的优缺点:  
堆的优点是可以动态分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的。
缺点就是要在运行时动态分配内存,存取速度较慢; 栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器。
另外,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。


方法区:

方法区是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据 。
相对而言,垃圾收集行为在这个区域比较少出现,但并非数据进了方法区就永久的存在了,这个区域的内存回收目标主要是针对常量池的回收和对类型的卸载,
当方法区无法满足内存分配需要时,将抛出OutOfMemoryError异常。


运行时常量池:
是方法区的一部分,它用于存放编译期生成的各种字面量和符号引用。

​http://hllvm.group.iteye.com/group/wiki/3053-JVM​

标签:Java,管理,对象,线程,内存,java,方法,分配
From: https://blog.51cto.com/u_15928064/5984727

相关文章

  • 第十七章《MySQL数据库及SQL语言简介》第4节:数据库表管理
    ​数据库表管理的操作包括创建数据库表、修改数据库表、查看数据库表属性、删除数据库表。为了能够创建出一张合理的数据表,必须先学习MySQL的数据类型,因此本小节首先讲解MyS......
  • Linux网络第四章:SSH远程管理及通过SSH实现服务器之间的免密连接
    目录一、SSH远程管理基础1、ssh协议2、ssh原理3、配置文件解析4、登录方法5、使用ssh协议传输的命令二、免密连接的实现1、免密连接原理 2、免密实现环境准备3......
  • Java程序员必看的 13 本 Java 书籍!
    关乎于程序员,除了做项目来提高自身的技术,还有一种提升自己的专业技能就是:多!看!书! 毕竟,书是学习的海洋呢!So,Java程序员你们准备好了吗?双手奉上Java程序员必读之热门书单。......
  • 初识Java
    初识JavaJava的特性和优势简单性就是c++语法的纯净版。没有头文件,指针运算,结构,联合,操作符重载,虚基类等等。面向对象面向对象是一种程序设计技术,他将重点放在数据(即对......
  • java中的HashSet的add()方法解析
     HashSet的add()方法解析示例代码如下:【可用于后续的源码追踪】1publicclassHomeWork04{2publicstaticvoidmain(String[]args){3HashS......
  • Javascript公共脚本库系列(二): 添…
    一.摘要本系列文章是为了抽象通用的,跨浏览器的脚本方法.本篇文章为我们的轻量级脚本库增加添加多播委托的方法.可以实现"单击页面空白区域则关闭页面上所有弹出层"等类似的......
  • java笔试题大全带答案(java笔试题大全带答案下载)
    谁有2008,2009,2010年计算机JAVA笔试试题和答案呢?2008年计算机Java笔试试题及答案2009年计算机考试Java笔试试题和答案2010年计算机考试Java笔试试题和答案下面地址也许有......
  • MyEclispe修改最大内存和最小内存的方法
    ......
  • 第一章:Java开发环境搭建
    感谢动力节点(放弃幻想,认清现实)1.知识框架2.计算机编程语言发展史?第一代语言:机器语言程序员直接编写二进制,一串二进制代码,例如:10010100010010001000..........
  • Java个人家乡博客源码
    概述个人博客相册家乡主题,用户注册后可以发布关于家乡的特色文章介绍,可以发布照片,相册管理,留言,评论,回复,收藏,关注演示视频https://www.bilibili.com/video/BV1iy4y1x7w6......