java存储数据

 java 数据存储区,主要以下五种:

  一、寄存器

  寄存器是集中在CPU指令的缓存区,是CPU直接作为数据交换,存取速度最快,一般用于复杂运算操作,不建议存放大数据,因寄存器数量有限,只存放要求非常快的数据,JAVA是不能直接操作寄存器。

  二、堆栈区

  堆栈,存放在RAM,也叫随机存储器,存取速度快,仅次于寄存器,以栈的方式进行存储,具有先进后出的特性。有一个叫堆栈指针直接跟CPU打招呼,向上移动则入栈(分配内存空间),向下移动则出栈(释放内存空间),故堆栈的内存分配/释放就是通过上下移动堆栈指针来操作的。基本类型(byte, short, int, float, double, boolean, char, long)8大类型(包括方法的参数和局部变量,不包括类字段)和引用类型的地址就存放于此。因堆栈是在编译器编译时要确定其大小和生命周期,故能确定什么时候能释放。

  优点:存取速度快。缺点:必须确定大小和生命周期,灵活性不够。

  三、堆区

  堆,也是存放在RAM,程序在编译时不需要指定空间大小,只在运行时才确定其大小,故增加了灵活性。所有以new引用类型的对象都存放于此,如: Object o = new Object(); 先在堆里分配一个空间用来存放Object对象,再在堆栈里分配一个空间标识为o,将这个空间存放刚刚分配的Object对象的内存地址。如果是数组,则堆栈存放的是数组的首地址。其中堆区也有个堆指针,堆指针总是指向当前分配的内存地址,如果要创建,则向下移动一格尚未分配的空间,不用再去整个堆区里查找未用空间,加速了分配内存速度,这是JVM做了优化。

  优点:因为在运行时动态指定大小,故灵活性好。缺点:存取速度慢。

  四、常量池

  常量池,主要用来存放永久不变的值(永久是指从程序运行到结束),如String,static final关键字修饰的变量 。这里要特别说明String,String本身是引用类型,因字符串在程序用的概率非常高,为了提高重用性和节省内存空间,JVM都会把所有出现过的字符串固定存放在常量池里,当下次用到这个字符串时,会先从常量池里找,如有则返回引用地址,没有则创建一个并返回引用地址。例如下:

  例1:

  String s1 = “abc”;

  String s2 = “bcd”;

  String s3 = “abc”;

  String s4 = s2;

  S1创建在常量池没找到字符串“abc”, 则新创建并返回内存地址(假设0x01)给s1; s2也是一样,创建并返回内存地址(0x02);s3因为”abc”已经存在常量池,故返回存在的内存地址0x01给s3; s4直接取s2所引用的内存地址0x02;

  例2:

  String s1 = “a”;

  String s2 = new String(“a”);

  String s3 = new String(“b”);

  String s4 = “a”.intern();

  s1就不说了,跟例1一样; s2是用new一个对象,不是直接赋值,过程是:先在常量池里找是否存在”a”,如果不存在则新创建,如果存在则忽略此步,然后再在堆里创建String对象并存放“a”,并返回堆里的引用地址(0x03)给s2,所以用new String会创建1个或2个对象; s3原理同上; s4是用对象的intern方法,该方法表示返回常量的内存地址。

  String 字符串一创建就不能更改,故开发者要提倡尽量少创建频率更改的字符串,如果确实有需要更改,应该用StringBuilder(非线程安全)或StringBuffer(线程安全)。String str = “a” + “b” + “c”, 对于字符串的+,编译器已经对此进行了优化,编译后的代码等效为String str = “abc”;

  五、非RAM区

  非RAM区,是不存在内存里,如硬盘或持久化流。
  

  总结:从以上的存储区可以看出,JAVA能操作到的,堆栈是最快的,能用基本类型解决问题就尽量用基本类型,基本类型还有个包装类,如int对应Integer,包装类是引用类型,创建的对象也是存在堆区里,如无特殊需要,尽量不要用包装类;关于常量池,尽量不要存太多,因为常量池永远不会变,生命周期从创建到程序结束为止,尤其是大数据对象,占用空间大,还有个是不经常用到的常量也尽量不要存放于此,节省内存使用概率

1.Java是如何管理内存的

java的内存管理就是对象的分配和释放问题。(其中包括两部分)

分配:内存的分配是由程序完成的,程序员需要通过关键字new为每个对象申请内存空间(基本类型除外),所有的对象都在堆(Heap)中分配空间。
释放:对象的释放是由垃圾回收机制决定和执行的,这样做确实简化了程序员的工作。但同时,它也加重了JVM的工作。因为,GC为了能够正确释放对象,GC必须监控每一个对象的运行状态,包括对象的申请、引用、被引用、赋值等,GC都需要进行监控。

2.什么叫java的内存泄露

在java中,内存泄漏就是存在一些被分配的对象,这些对象有下面两个特点,首先,这些对象是可达的,即在有向图中,存在通路可以与其相连(也就是说仍存在该内存对象的引用);其次,这些对象是无用的,即程序以后不会再使用这些对象。如果对象满足这两个条件,这些对象就可以判定为Java中的内存泄漏,这些对象不会被GC所回收,然而它却占用内存。

3.JVM的内存区域组成

java把内存分两种:一种是栈内存,另一种是堆内存
(1)在函数中定义的基本类型变量和对象的引用变量都在函数的栈内存中分配;
(2)堆内存用来存放由new创建的对象和数组以及对象的实例变量。在函数(代码块)中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量所分配的内存空间;在堆中分配的内存由java虚拟机的自动垃圾回收器来管理
堆和栈的优缺点

堆的优势是可以动态分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的。

缺点就是要在运行时动态分配内存,存取速度较慢;栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器。

另外,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值