论 Java 中的内存分配
-------------------------------------------------------------------------
Java内存分配主要包括以下几个区域:
1. 寄存器:我们在程序中无法控制
2. 栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中
3. 堆:存放用new产生的数据
4. 静态域:存放在对象中用static定义的静态成员
5. 常量池:存放常量
6. 非RAM(随机存取存储器)存储:硬盘等永久存储空间
------------------------------------------------------------------------------------
一. 寄存器(Registers):
这是速度最快的存储场所,因为寄存器位于处理器内部,这一点和其他的存储媒介都不一样。不过寄存器个数是有限的。
在内存中的寄存器区域是由编译器根据需要来分配的。我们程序开发人员不能够通过代码来控制这个寄存器的分配。
所以说,这第一个存储区域寄存器,我们只能够看看,而不能够对其产生任何的影响。,也没办法在程序里头感觉到寄存器的任何存在迹象。
JVM只设置了4个最为常用的寄存器。
pc程序计数器
optop操作数栈顶指针
frame当前执行环境指针
vars指向当前执行环境中第一个局部变量的指针
所有寄存器均为32位。
pc用于记录程序的执行。optop,frame和vars用于记录指向Java栈区的指针。
二. 栈(Stack):
又称堆栈
位于一般的RAM中。处理器经由指针提供直接支持。
当程序配置一块新的内存时,stack指针便往后移;释放内存时,指针则往前移。
这种方式不仅很快,效率也高,速度仅次于寄存器。
用于存放对象引用以及基本的数据类型对象,不能用于存储Java对象本身。
三. 堆(Heap):
一种通用的内存空间,用来存放Java对象。
Heap不同于stack之处在于,编译器不需知道究竟得从heap中配置多少空间,也不需知道从heap上配置的空间究竟需要存在多久。
因此,自heap配置存储空间可以获得高度的弹性。每当你需要产生对象,只需在程序中使用new,那么执行的时候,便会自heap配置空间。
当然,你得为这样的弹性付出代价:从heap配置空间,比从stack配置,所耗费的时间多了不少。
单论内存空间中的堆和栈:
1.栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方。Java自动管理栈和堆,程序员不能直接地设置栈或堆。
2.优缺点:
栈:
栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器。
但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。另外,栈数据在多个线程或者多个栈之间是不可以共享的,但是在栈内部多个值相等的变量是可以指向一个地址的
堆:
堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,Java的垃圾收集器会自动收走这些不再使用的数据。
但缺点是,由于要在运行时动态分配内存,存取速度较慢。
3.栈有一个很重要的特殊性,就是存在栈中的数据可以共享
四. 静态域:
静态存储区域就是指在固定的位置存放应用程序运行时一直存在的数据,Java在内存中专门划分了一个静态存储区域来管理一些特殊的数据变量如静态的数据变量,需要明确的一点就是,Java对象是不保存在这个地方的,而只是把对象中的一些特殊元素放置这。
类变量也叫静态变量,也就是在变量前加了static 的变量;
实例变量也叫对象变量,即没加static 的变量;
区别在于:
类变量和实例变量的区别在于:类变量是所有对象共有,其中一个对象将它值改变,其他对象得到的就是改变后的结果;而实例变量则属对象私有,某一个对象将其值改变,不影响其他对象;
特点:
这儿的“静态”(Static)是指“位于固定位置”(尽管也在RAM里)。程序运行期间,静态存储的数据将随时等候调用。可用static关键字指出一个对象的特定元素是静态的。但Java对象本身永远都不会置入静态存储空间。
例:
public class A{static int a = 0; //类变量private int b = 0; //实例变量 }public class B{public void main (String[] args){A a1 = new A();A a2 = new A();a1.a = 3; // 等同于 A.a = 3;a1.b = 4 ;System.out.println(a2.a); //结果为3//类变量是针对所有对象的,所以a1改变a,a2的a也改变System.out.println(a2.b); //结果为0//实例只改变自身的,所以a1对象的b改变,不影响对象a2的b变量 } }
五. 常量池:
常量池在java用于保存在编译期已确定的,已编译的class文件中的一份数据。它包括了关于类,方法,接口等中的常量,也包括字符串常量,如String s = "java"这种申明方式;当然也可扩充,执行器产生的常量也会放入常量池,故认为常量池是JVM的一块特殊的内存空间。
背景:
在Java对象中还有一类特殊的元素,我们叫做常量。由于常量的值是稳定不变的,如圆周率。为此把他们放在代码的内部是可行的。
不过有些时候,在进行一些嵌入式系统开发的时候,我们往往不这么做。而是会把常量元素跟代码分开来保存。
如我们会根据情况把常量的值存放在一些只读存储器中。这主要是为了一些特殊的功能考虑的。
如出于版权控制的需要。如在打印机上为了保护原装耗材的版权,往往把常量跟代码分开存放
特点:
在Java程序中,有很多的东西是永恒的,不会在运行过程中变化。
比如一个类的名字,一个类字段的名字/所属类型,一个类方法的名字/返回类型/参数名与所属类型,一个常量,还有在程序中出现的大量的字面值。
常数值通常直接置于程序代码内部。这样做是安全的,因为它们永远都不会改变。有的常数需要严格地保护,所以可考虑将它们置入只读存储器(ROM)。
六. 非RAM存储:
若数据完全独立于一个程序之外,则程序不运行时仍可存在,并在程序的控制范围之外。其中两个最主要的例子便是“流式对象”和“固定对象”。对于流式对象,对象会变成字节流,通常会发给另一台机器。而对于固定对象,对象保存在磁盘中。
即使程序中止运行,它们仍可保持自己的状态不变。对于这些类型的数据存储,一个特别有用的技巧就是它们能存在于其他媒体中。一旦需要,甚至能将它们恢复成普通的、基于RAM的对象
背景:
有时候,有些程序运行所需要的数据我们还会放置在其他地方。如在一些系统中需要用到流对象,这个对象的数据并没有保存在上面所谈到的任何一个存储区域,这个对象直接被转为为字节流,发送到其他的主机上去了。另外有一种叫做持久化的对象,其是被存储在硬盘中的
七. 论各类型内存的执行速度:
寄存器 > 堆栈 > 堆 > 其他
(C) 房上的猫 。 保留所有权利。
https://www.cnblogs.com/lsy131479/
如需转载,请注明出处!!!
转载于:https://www.cnblogs.com/lsy131479/p/8479232.html
论 Java 中的内存分配相关推荐
- Java基础-Java中的内存分配与回收机制
Java基础-Java中的内存分配与回收机制 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一. 二. 转载于:https://www.cnblogs.com/yinzhengji ...
- java中堆栈内存_Java堆空间与堆栈– Java中的内存分配
java中堆栈内存 Sometime back I wrote a couple of posts about Java Garbage Collection and Java is Pass by ...
- java中的内存分配原则
问题:Java中这些类.变量.字符串.方法,在内存中是怎样分配的? 首先,Java中的内存区域如下: ◆寄存器:我们在程序中无法控制 ◆栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是 ...
- Java中的内存分配
Java 程序在运行时,需要在内存中的分配空间.为了提高运算效率,就对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式. 栈 存储局部变量 堆 存储new出来的东西 方法区 ...
- 深入理解Java中的内存泄漏
理解Java中的内存泄漏,我们首先要清楚Java中的内存区域分配问题和内存回收的问题本文将分为三大部分介绍这些内容. Java中的内存分配 Java中的内存区域主要分为线程共享的和线程私有的两大区域: ...
- java中子类实例化过程中的内存分配
知识点: 子类继承父类之后,实例化子类时,内存中子类是如何分配内存的呢? 下面,自己会结合一个例子,解释一下,一个子类实例化过程中,内存是如何分配的 参考博客:http://www.cnblogs.c ...
- Java 中的内存溢出和内存泄露是什么?我给你举个有味道的例子
作者 l 会点代码的大叔(CodeDaShu) JAVA中的内存溢出和内存泄露分别是什么,有什么联系和区别,让我们来看一看. 01 内存泄漏 & 内存溢出 1. 内存泄漏(memory lea ...
- 形式参数内存在哪java_深入浅出Java中JVM内存管理
原标题:深入浅出Java中JVM内存管理 Java岗位面试,JVM是对程序员基本功考察,通常会问你对JVM了解吗?可以分几部分回答这个问题,首先JVM内存划分 | JVM垃圾回收的含义 | 有哪些GC ...
- java 物理内存_聊聊Java中的内存
JVM的内存 先放一张JVM的内存划分图,总体上可以分为堆和非堆(粗略划分,基于java8) 那么一个Java进程最大占用的物理内存为: Max Memory = eden + survivor + ...
最新文章
- mysql数据导库常用操作
- poj3070矩阵快速幂
- BZOJ 1251: 序列终结者( splay )
- 为什么 UEFI 方式启动的 U 盘必须使用 FAT32 文件系统?
- Your WebGL implementation doesn't seem to support hardware accelerated rendering. Check your browser
- NO--14 微信小程序,左右联动二
- Mysql中int(M)的含义
- 中文纠错(Chinese Spelling Correct)最新技术方案总结
- java 获取类方法_Java之反射机制三:获取类的方法
- 主成分分析法案例_主数据管理第一步——识别主数据
- 唐宇迪学习笔记12:sklearn构造决策树
- APP合规-超范围收集个人信息
- 后端系统开发利器,gflags概述
- 厦门大学 软件学院 夏令营
- 我猜这将是程序员副业接单赚外快的最好的平台!
- php liger 表格排序,LigerUI之grid表格点击表头标题排序实现
- css中设置body字体,css如何设置body字体颜色
- java基本微信小程序的快递代收派送系统 uniapp小程序
- “智慧青岛”里的海信力量
- 如何快速实现一个基于Nginx的网站监控场景 – 操作篇