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程序的时候会把它管理的内存区域划为几部分,这 ...
随机推荐
- JAVA Struts2 搭建
java struts 2搭建 1.web工程 2.将struts2 用到的jar包,拷贝到webcontent/webinf/lib文件夹.下 3.webcontent 下的web.xml 下 ...
- SpringMVC是什么?
一,首先是一个MVC框架. 在web模型中,MVC是一种很流行的框架,通过把Model,View,Controller分离,把较为复杂的web应用分成逻辑清晰的几部分,是为了简化开发,减少出错.还是为 ...
- VopSdk一个高逼格微信公众号开发SDK
一.我们的目标 分离基础参数和业务参数. 具有高重用和扩展性. 轻量级. 二.实现目标 (一)分离基础参数和业务参数 仔细分析所有接口,抽离出每个模块接口的公共参数. A.针对微信公众号所有接口分析( ...
- 极光的开源礼物「Aurora IMUI」
今日,奉上我们拙作,仅为开源世界献出绵薄之力. Aurora IMUI,一个通用的即时通讯(IM)UI 库.不局限于任何 IM SDK. 本 UI 库提供了消息列表.输入视图等常用组件. 初心 过去的 ...
- 【教程】发布NAServer到ArcGIS Server 10.4上[超详细]
前阵子对ArcGIS API For JavaScript的网络分析有兴趣,但是不知道其数据是如何获取的. 查阅API知道,AJS的网络分析只有三个功能:最短路径(RouteTask).最近设施点(C ...
- npm 常用命令详解
本文以Windows平台上做测试,以gulp为示例做教程,出自作者白树,转载请声明出处! 目录 npm是什么 npm install 安装模块 npm uninstall 卸载模块 npm updat ...
- java web (j2ee)学习路线 —— 将青春交给命运
RESON TO DO JAVA WEB:1.JAVA WEB(企业级) 2.Android和iOS过于火爆并且不兼容 一.JAVA WEB开发需要的知识储备 1. 基本的网页设计语言:H ...
- c#无限循环线程如何正确退出
c#无限循环线程如何正确退出 在主程序将要结束时,迅速正确退出无限循环执行的子线程.一般子线程循环执行会有一个指定的周期, 在子线程等待(或者睡眠)时,无法唤醒退出,尤其在执行周期较长时,子线程无法即 ...
- 成熟的C#网络通信框架介绍——ESFramework通信框架
(转自:http://www.cnblogs.com/zhuweisky/archive/2010/08/12/1798211.html) ESFramework通信框架是一套性能卓越.稳定可靠.强大 ...
- redis集群安装部署
(要让集群正常工作至少需要3个主节点,在这里我们要创建6个redis节点,其中三个为主节点,三个为从节点,对应的redis节点的ip和端口对应关系如下) 192.168.1.160:7000 192. ...