各种数据类型在jvm里的内存分配

jvm运行时数据区的简单介绍

JVM所管理的内存分为以下几个运行时数据区:程序计数器、Java虚拟机栈、本地方法栈、Java堆、方法区。

其中本文涉及到的主要有:java虚拟机站(简称java栈),java堆和方法区。

这里简单地普及一下这三种数据区的知识,java栈的读取速度是最快的(紧次与CPU的寄存器,跨平台性比寄存器好,android使用的是寄存器),但是里面的数据内存大小是编译时就已经分配好的,在运行时都不会改变;java堆的速度没有java栈的速度那么快,但是java堆里面的数据内存大小不是固定的;前面两种都会被java的垃圾收集器清除废弃的内存;方法区对于Sun
HotSpot来说,又称为“永久代”,虚拟机规范允许该区域可以选择不实现垃圾回收,相对而言,垃圾收集行为在这个区域比较少出现,该区域的内存回收目标主要针是对废弃常量的和无用类的回收。

基本数据类型

在java中,基本数据类型有:字节型(byte),短整型(short),整型(int),长整型(long),字符型(char),浮点型(float),双精度型(double),布尔型(boolean)。

基本数据类型都有一个共同点,就是它们的字节大小已经本身就已经固定的,所以,它们所需要的内存空间也是固定的。

根据上面jvm的简单介绍,基本数据类型实际上是放到java栈中的,这样可以保证基本数据类型的读取速度是最快的,而且基本数据类型用得也比较多。

对象实例及其引用

对于对象实例,总所周知,它的内存大小是不确定的,而且它也经常需要被垃圾收集器回收内存,所以它实际上是放在jvm里的java堆中;

对于引用类型(即对象引用),它的大小是固定的,而且在运行时需要快速找到引用,它实际上是放在jvm的java栈中。

对于Object obj = new Object(); 在java堆中有两种实现方法,一种是在java堆中多实现了一个句柄池,句柄池中放入到对象实例数据的指针,即java栈中的引用指向java堆中句柄池中的对象实例数据指针,再拿到实例数据;另一种是java堆中没用句柄池,java栈中的引用直接指向java堆中的实例数据。两种实现对比:第一种实现多了一个中间过程,当对象实例数据地址移动了,java栈中的引用不用变,只变句柄池的指针就行了;第二种实现,少了一个指针指向过程,速度比第一种快,但对象实例数据地址移动了,java栈中的引用也要改变。

借用一篇博文的图片:第一种

第二种:

字符串类型

String是一个特殊的对象,它的内存存放不用于普通对象类型。

首先,它是一个常量,一旦确定好就不会再改变,如:String str = "erdangjiade" + "  " + "blog";  这句代码会将"erdangjiade"、"  "和"blog"分别放入jvm里面,再将"erdangjiade  blog"放入jvm里面。所以为什么用StringBuffer的原因是StringBuffer是可变的。

讲了那么多,那么到底String是放去jvm哪里呢,如果从百度上找,会找到很多误导人的答案,字符串实际上是放在字符串常量池里面,字符串常量池是在常量池里面,而常量池是在方法区里面。所以字符串实际上是放在方法区里面的。

但是字符串引用还是存放在java栈中,直接指向方法区的常量池。

如果是new String("");  这种方法得到的字符串不是放入字符串常量池中,而是当成一个普通对象放在java堆中的,例子:

String str = "erdangjiade";

String newStr = new String("erdangjiade");

当判断str==newStr时,会返回false,因为它们的地址不一样。(普及一个知识:==是比较两个对象的地址,equal()是比较对象数据是否相等)

方法区还存放被虚拟机加载的类信息,如:类类型,父类型,接口,方法及其方法参数等,反射中经常用到。所以方法区存放的数据特点是:静态的,基本的,共享的。

欢迎大家补充说明

参考文章:

兰亭风雨的【深入Java虚拟机】之一:Java内存区域与内存溢出

ZangXT的小例子:如何说明String常量池的位置

各种数据类型在jvm里的内存分配

时间: 2024-10-06 22:20:58

各种数据类型在jvm里的内存分配的相关文章

JVM学习之内存分配一

转自:http://blog.csdn.net/mazhimazh/article/details/16879055,多谢博主分享 我们知道计算机的基本构成是:运算器.控制器.存储器.输入和输出设备,那这个JVM也是有这成套的元素,运算器是当然是交给硬件CPU还处理了,只是为了适应“一次编译,随处运行”的情况,需要做一个翻译动作,于是就用了JVM指令集,这与汇编的命令集有点类似,每一种汇编命令集针对一个系列的CPU,比如8086系列的汇编也是可以用在8088上的,但是就不能跑在8051上,而JV

【深入理解JVM】:内存分配与回收策略

Java技术体系中所提倡的自动内存管理最终可以归结为自动化地解决了两个问题:给对象分配内存以及回收分配给对象的内存. 对象的内存分配,往大方向讲,就是在堆上分配,对象主要分配在新生代的Eden区上,如果启动了本地线程分配缓冲,将按线程优先在TLAB上分配.少数情况下也可能会直接分配在老年代中,分配的规则并不是百分之百固定的,其细节取决于当前使用的是哪一种垃圾收集器组合,还有虚拟机中与内存相关的参数的设置. 本文中的内存分配策略指的是Serial / Serial Old收集器下(ParNew /

阿里Java岗面试必备JVM指南:内存分配+垃圾回收+调优+类加载器等

前言 作为 Java 的从业者,在找工作的时候,一定会被问及关于 JVM 相关的知识. JVM 知识的掌握程度,在很多面试官眼里是候选人技术深度的一个重要评判标准.而大多数人可能没有对 JVM 的实际开发和使用经验,接下来这一系列文章将带你深入了解 JVM 需要掌握的各个知识点.这也将帮助你完成从初级程序员到高级程序员的转变. 今天分享一份平时学习整理的Java程序员必备的JVM学习文档,这份文档不管是懂得JVM的开发者和刚刚学习的朋友都是一份非常不错的内容,同时也是面试复习的精选文档!还准备了

理解JVM之GC&内存分配

垃圾回收机制 对象存活判定算法 垃圾收集算法 HotSpot算法实现和垃圾收集器 内存分配和回收策略 对象存活判定算法(JVM回收那些对象) 概念:四种引用类型 强引用:及时内存不足也不会被GC,不会随意回收强引用对象:即使抛出OOM(OutOfMemoryError),也不会随意回收强引用对象 软引用:只有内存不足时,会被GC:回收后内存不足会抛出OOM异常 弱引用:无论当前内存是否充足都会被GC 虚引用:任何时候都会别GC a.引用计数算法:给对象添加一个引用计数器,每当有一个地方引用他的时

JVM学习之内存分配和垃圾回收

阅读书籍:Java虚拟机精讲(仅个人阅读后总结) 根据受访权限可分为:线程共享内存区和线程私有区 线程共享区: 1.java堆区:储存对象实例: 2.方法区:储存 运行时常量池.字段和数据.构造函数和普通方法的字节码内容以及类.实例.接口初始化需要用到的特殊方法等数据: 3.运行时常量池: 线程私有内存区: 1.PC寄存器:如果当前线程所执行的方法是一个java方法,那么PC寄存器就会存储正在执行的字节码指令地址,反之如果是native方法,这是PC寄存器的值为空(undefined): 2.j

JVM 运行时的内存分配

首先我们必须要知道的是 Java 是跨平台的.而它之所以跨平台就是因为 JVM 不是跨平台的.JVM 建立了 Java 程序和操作系统之间的桥梁,JVM 是用 C 语言编写,而 C 语言不具备跨平台的特性.所以对于 Windows 平台,Java 有基于 Windows 平台的 JVM:对于 Linux 平台,Java 也有基于 Linux 平台的 JVM等等.不同的操作系统有不同的 JVM,所以我们编写的 Java 代码能在各个平台上运行,是因为有各个平台的 JVM. 而 Java 的内存分配

JVM总结(二):JVM的内存分配策略

这节我们总结一下JVM中的内存分配策略.目录如下: 内存分配策略 对象优先在新生代Eden分配 大对象直接进入老年代 长期存活的对象将进入老年代 动态对象年龄判定 空间分配担保 内存分配策略 Java技术体系中所提倡的自动内存管理可以归结于两个部分:给对象分配内存以及回收分配给对象的内存. 我们都知道,Java对象分配,都是在Java堆上进行分配的,虽然存在JIT编译后被拆分为标量类型并简介地在栈上进行分配.如果采用分代算法,那么新生的对象是分配在新生代的Eden区上的.如果启动了本地线程分配缓

[转载]C语言程序的内存分配方式

"声明一个数组时,编译器将根据声明所指定的元素数量为数量为数组保留内存空间."其实就是编译器在编译的过程中,会加入几条汇编指令在程序里处理内存分配,并不是说编译时就分配了内存,不要理解错了. ------------------- 1.内存分配方式 内存分配方式有三种: [1]从静态存 储区域分配.内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.例如全局变量,static变量. [2]在栈上创建. 在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结

linux内存分配与回收

前言 之前在实习时,听了 OOM 的分享之后,就对 Linux 内核内存管理充满兴趣,但是这块知识非常庞大,没有一定积累,不敢写下,担心误人子弟,所以经过一个一段时间的积累,对内核内存有一定了解之后,今天才写下这篇博客,记录以及分享. [OOM - Out of Memory]内存溢出 内存溢出的解决办法: 1.等比例缩小图片 2.对图片采用软引用,及时进行 recycle( ) 操作. 3.使用加载图片框架处理图片,如专业处理图片的 ImageLoader 图片加载框架,还有XUtils 的