Java对于内存的需要知道的知识
内存
内存大家都知道(当然不是硬盘啊)。与c、c++相比呢,Java在内存管理的方面一个优越之处就是我们不用显式的去对对象进行内存的分配和内存的回收,可能有人会着迷于对内存使用分配的这种快感,但是随着程序变大,对于内存的维护工作也就越来越大。Java的JVM的自动内存管理机制,凸显出了强大的优越感。。。。
但反而是因为这样的一个现状,就弱化了我们在写Java程序时遇到内存溢出等问题时的定位能力和解决问题的能力。就在这个时候一本书应运而生--- 《深入理解java虚拟机》 这本书也算是我旁边落灰最严重的一本了,但写程序就是这样如果不沉到底,程序浮于表面那就只是单纯的应用,不能变的熟练。
只有我们真正的了解了JVM如何管理内存后,才能遇见OutOfMemory错误时,快速的根据异常日志信息定位和解决问题。
Java内存分配方式
咱们看看上面这张图,颜色这么鲜艳,这次一定能记住了!
静态 存储区
内存在程序编译的时候就已经分配好了,这块内存在程序的整个运行期间都存在。比如,static 、全局变量
在 栈 上创建
在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分匹配运算内置于处理器的指令集中、效率很高、但是分配的内存容量非常有限。
在 堆 上分配
动态内存分配。在c和c++中运行程序时用 malloc 或 new申请任意大小的内存,我们需要自己决定自己在何时何地使用使用free和delete来释放内存。
Java虚拟机内存模型是Java程序运行的基础。虚拟机在执行Java程序的过程中会把他所管理的内存划分为若干的不同的数据区域,ok,这里加重 是分为不同的数据区域,这些区域都有自己的用途以及创建和销毁的时间。看一下下图,
太好了,又画了一个带颜色的图~那就说一说为什么带不同的颜色吧
- 紫色,由所有线程共享的数据区
- 线程隔离的数据区
程序计数器
寄存器里面有一个叫指令寄存器,用来储存现在正在被运行的指令。想象一下,在JVM中怎么办,程序寄存器就是这样的功能。
程序技术器是一块较小的内存空间,它可以看做是当前线程所执行的字节码的行号指示器。“字节码”就是Java程序被编译之后的形态,JVM有字节码解释器,这个解释器要解释程序的哪段,就由这个程序技术器来决定的。
Java虚拟机栈
Java虚拟机栈也是线程私有的,生命周期与线程相同,虚拟机栈描述的是Java方法执行的内存模型。每个方法在执行的同时会创建栈帧,保存
- 局部变量表
- 操作数栈
- 动态链接
- 方法出口
每个方法从调用直到执行完成的过程,就对应整一个栈帧在虚拟机栈中入栈和出栈的过程。
平时咱们在讨论的时候总会提到“栈”和“堆”这两种内存区域,那么其中的栈,就是这里所指的栈,更细一点说,就是虚拟机栈中局部变量的部分。
在换一个方面讲解一下,虚拟机栈是用来被快速访问的存储区域,一般该区域位于通用RAM里,
这个RAM叫随机存储器,是与CPU直接交换数据的内存存储器,也叫主存,可以随时随地的写,而且速度快,通常作为操作系统或其他正在运行中的程序的临时数据存储媒介。
在虚拟机栈中,使用栈指针来访问处理器。我们都学过栈这种数据结构,它是一种快速有效的 分配 存储的方法,存储速度仅次于寄存器,堆栈指针若向下移动,则分配新的内存,若向上移动则释放那些内存。由于Java编译器需要预先去生成相应的内存空间,所以,当我们尝试创建程序的时候,Java编译器必须知道被存储在站内的所有数据的确切大小和声明周期。一遍可以像上面描述的那样去分配内存空间。
栈相对于堆的优势就是比堆存取快,在栈中重要被用来存放一下基本类型的变量,例如int、short、long、byte、float、double、boolean、char,以及对象的引用(对象本身一般都存放在堆中)
StackOverFlow和OutOfMemoryError
Java虚拟机规范允许Java栈的大小是动态的或者是固定不变的。如果线程在计算过程中,请求的栈深度大于最大可用的栈深度,则在程序运行过程中会抛出StackOverFlow异常、如果Java栈可以动态扩展,而在扩展的过程中没有足够的内存空间支持栈的发展,在运行过程中会抛出OutOfMemoryError异常。
本地方法栈
本地方法栈与虚拟机栈所发挥的作用十分相似,区别就是虚拟机栈执行Java(字节码)的方法,本地栈是为虚拟机使用到Native方法。
Java堆
Java堆(Heap)是Java虚拟机所管理的内存中最大的一块。堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。次内存却与的唯一目的就是存放对象示例,刚才在栈的部分也说了,栈中存的是对象的索引,而对象的实例存放在堆中。
在Java虚拟机规范中描述:所有的对象实例以及数组都要被在堆上分配内存。
GC(Garbage Collection)垃圾回收
由于堆和栈结构上的不同,所以其内存回收的机制也是不一样的。
Java中对可以细分为:
- 新生代
- 老年代
再细分...
- Eden空间
- From Survivor空间
- To Survivor
在内存的角度来看,线程共享的Java堆中可能划分出多个线程私有的分配缓存区(Thread Local Allocation Buffer,TLAB)。Java堆可以处于物理上不连续的内存空间中,只要逻辑上是连续的即可,就像我们的磁盘空间一样,在实现是,既可以实现成固定大小的,也可以是可扩展的,不过当前主流的虚拟机都是按照可扩展来实现的
-Xmx
-Xms
在堆中没有内存完成实例分配,并且堆也无法在扩展时会抛出OutOfMemoryError异常。
方法区
方法区和Java堆是一样的,是各个线程共享的内存区域,他用于储存已被虚拟机加载的类的信息、常量、静态变量、即时编译器编译后的代码等数据。
Java对于内存的需要知道的知识的更多相关文章
- 关于Java虚拟机内存原型的基本知识
Java虚拟机内存原型的六个部分: 1.寄存器:我们在程序中无法控制 2.栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中 3.堆:存放用new产生的数据 4.静态域:存放在 ...
- JVM基础系列第6讲:Java 虚拟机内存结构
看到这里,我相信大家对于一个 Java 源文件是如何变成字节码文件,以及字节码文件的含义已经非常清楚了.那么接下来就是让 Java 虚拟机运行字节码文件,从而得出我们最终想要的结果了.在这个过程中,J ...
- Java的内存管理机制之内存区域划分
各位,好久不见.先做个预告,由于最近主要在做Java服务端开发,最近一段时间会更新Java服务端开发相关的一些知识,包括但不限于一些读书笔记.框架的学习笔记.和最近一段时间的思考和沉淀.先从Java虚 ...
- 【转】Java学习---内存泄露与溢出的区别
Java内存泄露与溢出的区别 Java内存泄漏就是没有及时清理内存垃圾,导致系统无法再给你提供内存资源(内存资源耗尽): 而Java内存溢出就是你要求分配的内存超出了系统能给你的,系统不能满足需求,于 ...
- java虚拟机---内存
java虚拟机---内存 Java虚拟机,即JVM,负责运行java程序,每个java程序都运行在一个具体jvm实例上.Java虚拟机的体系架构分为:类装载子系统.运行时数据区.执行引擎.类装载子系统 ...
- [ 转载 ] Java Jvm内存介绍
一.基础理论知识 1.java虚拟机的生命周期: Java虚拟机的生命周期 一个运行中的Java虚拟机有着一个清晰的任务:执行Java程序.程序开始执行时他才运行,程序结束时他就停止.你在同一台机器上 ...
- Java 堆内存和栈内存
看了一些别人总结的博客,感觉对堆内存和栈内存有了一个初步的认识.所以来写写自己对堆内存和栈内存的理解. Java把内存分成两种,一种叫做栈内存,一种叫做堆内存. 在函数中定义的一些基本类型的变量和对象 ...
- 从一道面试题深入了解java虚拟机内存结构
记得刚大学毕业时,为了应付面试,疯狂的在网上刷JAVA的面试题,很多都靠死记硬背.其中有道面试题,给我的印象非常之深刻,有个大厂的面试官,顺着这道题目,一直往下问,问到java虚拟机的知识,最后把我给 ...
- 深入探究JVM(1) - Java的内存区域解析
http://blog.csdn.net/sczyh22/article/details/46652901<br>Java 虚拟机在执行Java程序的时候会把它管理的内存区域划为几部分,这 ...
随机推荐
- 在c++中,标准输入string时cin 与getline两个函数之间的区别
cin: cin函数是标准库的输入函数,在读取string时遵循以下规则: 1)读取并忽略开头所有的空白符(包括空格.换行符.制表符). 2)读取字符直到遇到空白符,读取终止. 例如: 当输入的是“ ...
- 关于AysncController的一次测试(url重写后静态页文件内容的读取是否需要使用异步?)
因为做网站的静态页缓存,所以做了这个测试 MVC项目 准备了4个Action,分两组,一组是读取本地磁盘的一个html页面文件,一组是延时2秒 public class TestController ...
- 通过web对.exe程序进行更新和修改
实现功能:通过网站更新用户的软件,需要联网,也可以通过本地网站更新局域网用户软件. 根本实现:1.一个网站(我用的是自己的www.aq36.xyz ,本地就可以,可以用localhost)然后运行up ...
- MongoDB基础教程系列--第九篇 MongoDB 分片
1.分片介绍 分片(sharding)是将数据拆分,将其分散存到不同机器上的过程.MongoDB 支持自动分片,可以使数据库架构对应用程序不可见.对于应用程序来说,好像始终在使用一个单机的 Mongo ...
- 2017/4/27-Gradle的配置与Spring的下载
Gradle的配置与Spring的下载 1.Gradle 1) 介绍 Gradle是一个基于Groovy的构建工具,类似Maven,但是比其更加简单轻便.它可以自动化地进行软件构建.测试.发布.部署. ...
- OK 开始实践书上的项目一:即使标记
OK 开始实践书上的项目一:及时标记 然而....又得往前面看啦! ----------------------我是分割线------------------------ 代码改变世界
- IOS的Application以及IOS目录的介绍
1.UIApplication介绍 .UIApplication对象是应用程序的象征 .每一个应用都有自己的UIApplication对象,而且是单例的 .通过[UIApplication share ...
- W10上面DOSBOX安装
第一步:下载好MASM.exe.debug.exe.link.exe.将其放在根目录下面.我们以后自己编写的汇编代码也是在此目录下.如图: 第二步:我这里的文件夹名称是Assembly那么这个也就是待 ...
- MySql5.7环境搭建
1. 安装mysql的linux系统 [root@grewan ~]# cat /etc/redhat-release CentOS release 6.7 (Final) [root@grewan ...
- spring boot入门
一.对spring boot的解释:(百度百科) Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行 ...