《Android虚拟机》--内存分配策略
No1:
Java在内存分配时会涉及到以下区域:
寄存器:我们在程序中无法控制
栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中
堆:存放用new产生的数据
静态域:存放在对象中用static定义的静态成员
常量池:存放常量
非RAM存储:硬盘等永久存储空间
No2:
栈中的数据都是以栈帧(Stack Frame)的格式存在的。栈帧是一个内存区块,是一个数据集,是一个有关方法(Method)和运行期数据的数据集。
栈帧中主要保存如下3种数据:
1)本地变量(Local Variables):包括输入参数和输出参数以及方法内的变量
2)栈操作(Operand Stack):记录出栈、入栈的操作
3)栈帧数据(Frame Data):包括类文件、方法等
No3:
堆内存用来存放由关键字new创建的对象和数组。在堆中分配的内存,由Java虚拟机的自动垃圾回收器来管理
No4:
引用变量是普通的变量,定义时再栈中分配,引用变量在程序运行到其作用域之外后被释放。而数组和对象本身在堆中分配,即使程序运行到使用new产生数组或者对象的语句所在的代码块之外,数组和对象本身占据的内存不会被释放,数组和对象在没有引用变量指向它时,才变为垃圾,不能再被使用,但仍然占据内存空间不放,在随后的一个不确定的时间被垃圾回收器收走(释放掉)。这也是Java比较占内存的原因。实际上,栈中的变量指向堆内存中的变量,这就是Java中的指针。
No5:
常量池指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据。除了包含代码中所定义的各种基本类型和对象型(如string及数组)的常量值(final)还包含一些以文本形式出现的符号引用。
1)类和接口的全限定名 2)字段的名称和描述符 3)方法的名称和描述符
虚拟机必须为每个被装载的类型维护一个常量池。常量池就是该类型所用到常量的一个有序集合,包括直接常量(string,integer和floating point常量)和对其他类型,字段和方法的符号引用。
No6:
一个Java虚拟机实例只存在一个堆内存,堆内存的大小是可以调节的。类加载器读取了类文件后,需要把类、方法、常变量放到堆内存中,以方便执行器执行,堆内存分为三部分:
1)Permanent Space 永久存储区
永久存储区是一个常驻内存区域,它存储的是运行环境必需的类信息,被装载进此区域的数据是不会被垃圾回收器回收掉的,关闭Java虚拟机才会释放此区域所占用的内存。
2)Young Generation Space 新生区
3)Tenure generation space 养老区
No7:
堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。
No8:
栈的优势是存取速度比堆要快,仅次于寄存器,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。
No9:
Java虚拟机内存模型中定义的访问操作与物理计算机处理的基本一致。Java通过多线程机制使得多个任务同时执行处理,所有的线程共享Java虚拟机内存区域main memory,而每个线程又单独的有自己的工作内存,当线程与内存区域进行交互时,数据从主存复制到工作内存,进而交由线程处理(操作码+操作数)。
No10:
运行时的数据区域:程序计数器(Program Counter Register)、Java的虚拟机栈(VM Stack)、本地方法栈(Natvie Method Stack)、Java堆(Java Heap)、方法区、运行时常量池、直接内存
No11:
程序计数器:
在Java虚拟机的概念模型里,字节码解释器通过改变这个计数器的值来选取下一条需要执行的字节码指令。为了在线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,并且各条线程之间的计数器互不影响,能够独立存储,我们称这类内存区域为线程私有的内存。
此内存区域是唯一一个在java虚拟机规范中没有规定任何OutOfMemoryError情况的区域。
No12:
Java的虚拟机栈
虚拟机栈描述的是Java方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程
下面列出的两种异常情况与Java栈相关
1)如果线程请求的栈深度大于虚拟机所允许的深度,则Java虚拟机将抛出StackOverflowError异常
2)如果虚拟机栈可以动态扩展,但是无法申请到足够的内存来实现扩展,或者不能得到足够的内存为一个新线程创建初始Java栈,则Java虚拟机将抛出OutOfMemorError异常
No13:
本地方法栈:
本地方法栈中执行的是非Java语言编写的代码,例如C或C++,它们通常在每个线程被创建时分配在每个线程被创建时分配在每个线程基础上的。
No14:
Java堆:
Java堆是类实例和数组的分配空间,是一块所有线程共享的内存区域。堆在虚拟机启动时创建,是Java虚拟机所管理的内存中最大的一块。Java堆内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。Java堆可以处于物理上不连续的内存空间中,只要逻辑上是连续的即可。
No15:
方法区:
方法区(Method Area)与Java堆一样,是各个线程共享的内存区域,用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器变异后的代码等数据。
No16:
运行时常量池:
用于存放编译器生成的各种字面量和符号引用,常量池也是方法区的一部分。
No17:
访问对象的主流方式有两种:
1)使用句柄:Java堆中将会划分出一块内存来作为句柄池,reference中存储的就是对象的句柄地址,而句柄中包含了对象实例数据和类型数据各自的具体地址信息。
2)使用直接指针:Java堆对象的布局中就必须考虑如何放置访问类型数据的相关信息,reference中直接存储的就是对象地址。
这两种访问方式各有优势:
使用句柄访问方式的最大好处就是reference中存储的是稳定的句柄地址,在对象被移动(垃圾收集时移动对象是非常普遍的行为)时只会改变句柄中的实例数据指针,而reference本身不需要被修改
使用直接指针访问方式最大好处就是速度更快,它节省了一次指针定位的时间开销,由于对象的访问在Java中非常频繁,因此这类开销积少成多猴也是一项非常可观的执行成本
No18:
内存泄露的分类:
1)常发性内存泄露
发生内存泄露的代码会被多次执行,每次被执行的时候都会导致一块内存泄露
2)偶发性内存泄露
发生内存泄露的代码只有在某些特定环境下或操作过程中才会发生。
3)一次性内存泄露
发生内存泄露的代码只会被执行一次,或者由于算法上的缺陷,导致总会有一块且仅一块内存发生泄露。
4)隐式内存泄露
程序在运行过程中不停地分配内存,但是直到程序结束时才释放内存。对于一个服务器程序来说,需要运行几天,几周甚至几个月,不及时释放内存也可能导致最终耗尽系统的所有内存。
No19:
内存管理的核心就是两个部分:分配内存和回收内存。Java语言使用new操作符来分配内存
No20:
所有的对象都有一个相同的头部clazz和lock:
1)clazz:指向该对象的类对象,类对象用来描述该对象所属的类,这样可以很容易的从一个对象获取该对象所属的类的具体信息
2)lock:是一个无符号整数,用以实现对象的同步
3)data:用于存放对象数据,根据对象的不同数据区的大小是不同的
No21:
在Dalvik虚拟机实现有3个时机可以触发垃圾收集的运行
1)程序员显式的调用System.gc()
2)内存分配失败时
3)如果分配的对象大小超过384KB,运行并发标记(concurrent mark)
《Android虚拟机》--内存分配策略的更多相关文章
- 深入理解java虚拟机---内存分配策略(十三)
转载请注明原文地址:https://blog.csdn.net/initphp/article/details/30487407 Java内存分配策略 使用的ParNew+Serial Old收集器组 ...
- 小白请教几个关于Java虚拟机内存分配策略的问题
最近在看周志明所著的<深入理解Java虚拟机>,有几个问题不太明白,希望对虚拟机有研究的哥们儿帮我解答一下.先说一下我进行试验的环境: 操作系统:Mac OS X 10.11.6 EI C ...
- 《深入理解Java虚拟机》内存分配策略
上节学习回顾 1.判断对象存活算法:引用计数法和可行性分析算法 2.垃圾收集算法:标记-清除算法.复制算法.标记-整理算法 3.垃圾收集器: Serial:新生代收集器,采用复制算法,单线程. Par ...
- 深入理解java虚拟机(2)------垃圾收集器和内存分配策略
GC可谓是java相较于C++语言,最大的不同点之一. 1.GC回收什么? 上一篇讲了内存的分布. 其中程序计数器栈,虚拟机栈,本地方法栈 3个区域随着线程而生,随着线程而死.这些栈的内存,可以理解为 ...
- java虚拟机学习-JVM内存管理:深入垃圾收集器与内存分配策略(4)
Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来. 概述: 说起垃圾收集(Garbage Collection,下文简称GC),大部分人都把这项 ...
- 深入理解java虚拟机_第三章(上)----->垃圾收集器与内存分配策略
1. 前言 这一版块内容比较多,分为两篇文章来做笔记.本文讲述上半部分垃圾收集部分;下一篇文章写内存分配部分. 概述 对象已死吗? 引用技术算法 可达性分析算法 再谈引用 两次标记 回收方法区 2. ...
- 深入理解java虚拟机----->垃圾收集器与内存分配策略(下)
1. 前言 内存分配与回收策略 JVM堆的结构分析(新生代.老年代.永久代) 对象优先在Eden分配 大对象直接进入老年代 长期存活的对象将进入老年代 动态对象年龄判定 空间分配担保 2. 垃圾 ...
- 【java虚拟机序列】java中的垃圾回收与内存分配策略
在[java虚拟机系列]java虚拟机系列之JVM总述中我们已经详细讲解过java中的内存模型,了解了关于JVM中内存管理的基本知识,接下来本博客将带领大家了解java中的垃圾回收与内存分配策略. 垃 ...
- 《深入理解Java虚拟机》-----第3章 垃圾收集器与内存分配策略
Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的“高墙”,墙外面的人想进去,墙里面的人却想出来. 3.1 概述 说起垃圾收集(Garbage Collection,GC),大部分人都把这 ...
- 《深入java虚拟机》读书笔记之垃圾收集器与内存分配策略
前言 该读书笔记用于记录在学习<深入理解Java虚拟机--JVM高级特性与最佳实践>一书中的一些重要知识点,对其中的部分内容进行归纳,或者是对其中不明白的地方做一些注释.主要是方便之后进行 ...
随机推荐
- OpenCV---高斯模糊(均值模糊的另一种)
高斯分布: 高斯模糊的原理 一:图像产生高斯噪声循环代码实现(耗时) def clamp(pv): #使我们的随机值在0-255之间 : : return pv import cv2 as cv im ...
- gulp教程之gulp-autoprefixer
现在浏览器的种类很多,不同浏览器的内核不同,同一浏览器也有很多不同的版本,很多css属性为了兼容浏览器需要加上特定的前缀,比如chrome的前缀是-webkit-,firefox前缀是-moz-等. ...
- leetcode 刷题日志 2018-03-26
58. 最后一个单词的长度 分析:找最后一个非空格,向前找 int lengthOfLastWord(string s) { int i = s.find_last_not_of(' '); int ...
- HDU 5213 分块 容斥
给出n个数,给出m个询问,询问 区间[l,r] [u,v],在两个区间内分别取一个数,两个的和为k的对数数量. $k<=2*N$,$n <= 30000$ 发现可以容斥简化一个询问.一个询 ...
- .Net各版本新特性
序言 C# 1.0 (2002) public interface IDateProvider { DateTime GetDate(); } 隐式接口实现 public class DefaultD ...
- 提高效率!15款最好的 Bug 跟踪应用程序
当涉及到开发项目时,其中比较重要的事情是它需要某种形式的错误和问题跟踪工具来发现和解决问题,否则会浪费大量的时间. 此外,你总是要标签应用来标示那些悬而未决的问题,而这种分期执行的项目进度将帮助您 ...
- 【BZOJ】3036: 绿豆蛙的归宿
[题意]给定DAG带边权连通图,保证所有点都能到达终点n,每个点等概率沿边走,求起点1到终点n的期望长度.n<=10^5. [算法]期望DP [题解]f[i]表示到终点n的期望长度. f[n]= ...
- IDEA常见错误
1. inspects a maven model for resolution problems 在添加Maven依赖的时候,报了inspects a maven model for resolut ...
- Batch Gradient Descent vs. Stochastic Gradient Descent
梯度下降法(Gradient Descent)是用于最小化代价函数的方法. When $a \ne 0$, there are two solutions to \(ax^2 + bx + c = 0 ...
- bzoj 3083 树链剖分
首先我们先将树提出一个根变成有根树,那么我们可以通过树链剖分来实现对于子树的最小值求解,那么按照当前的根和询问的点的相对位置关系我们可以将询问变成某个子树和或者除去某颗子树之后其余的和,前者直接询问区 ...