《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高级特性与最佳实践>一书中的一些重要知识点,对其中的部分内容进行归纳,或者是对其中不明白的地方做一些注释.主要是方便之后进行 ...
随机推荐
- springboot创建maven多模块项目
SpringBoot创建maven多模块项目 项目结构 该项目名称为springboot-maven-multi,由springboot-maven-multi.user-dao.user-domai ...
- bzoj 2375: 疯狂的涂色
2375: 疯狂的涂色 Time Limit: 5 Sec Memory Limit: 128 MB Description 小t非常喜爱画画,但是他还是一个初学者.他最近费尽千辛万苦才拜到已仙逝的 ...
- HDU 2588 思维 容斥
求满足$1<=X<=N ,(X,N)>=M$的个数,其中$N, M (2<=N<=1000000000, 1<=M<=N)$. 首先,假定$(x, n)=m$ ...
- js中不能做变量名的字符
JavaScript中不能作为变量名的关键字和保留字总结: 1.js中的关键字: break case catch continue default delete do else finally fo ...
- 在Unity中实现屏幕空间反射Screen Space Reflection(3)
本篇讲一下相交检测的优化.有两个措施. 线段相交检测 之前的检测都是检测光线的终点是否在物体内.我们可以尝试检测光线的线段是否与物体相交. 比如说有一个非常薄的物体,光线差不多垂直于它的表面.如果用普 ...
- Django之组合搜索组件(一)
什么是组合搜索呢? 比如你想买车,但手里只有10万块!所以你只能在10万块的车里挑选,但你喜欢黑色,因为觉得很高端大气上档次,说白了就是装逼杠杠的!之后售车姐给你拿了个表表,你看到了低于10万块且颜色 ...
- Verilog笔记.5.同步、异步
在数字电路中经常有同步synchronism.异步asynchronism的概念.异步指输入信号和时钟无关:同步指输入信号和时钟信号有关,实际上就是输入信号和时钟信号进行了与运算或者与非运算.实际开发 ...
- Sublime text 3中文汉化教程
想弄个中文版的sublime,居然可以不用重新下载汉化包或者重新下载简体中文版了~而是只需要安装个插件即可! 工具/原料 电脑 sublime text3编辑器 方法/步骤 启动并进入s ...
- iOS中响应者链条-触摸事件,hitTest方法坐标转换
总体来说,分2个步骤: 一,从上到下寻找合适的控件来处理这个触摸事件.如下图,如果点击了黄色4,则UIApplication -> UIWindow -> 1白色 -> 2橙色 -& ...
- Vuex-Action
Action 类似于 mutation,不同在于: Action 提交的是 mutation,而不是直接变更状态. Action 可以包含任意异步操作. 让我们来注册一个简单的 action: con ...