JAVA里String数组在内存分配中分配的空间每个占几个字节?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA里String数组在内存分配中分配的空间每个占几个字节?相关的知识,希望对你有一定的参考价值。

public class Car
String name;

public Car(String name)
this.name = name;


public class Test01

public static void main(String[] args)
int[] a = new int[3];
a[0] = 20;
a[2] = 32;
a[1] = 45;

Car[] cars = new Car[4];
cars[0] = new Car("奔驰");



比如这个程序,堆中分配4个空间给数组Car,3个空间给int,每个空间占几个字节?另外Char占几个字节?

java中一个int占4个字节,由于java是unicode编码,一个char可以占两个字节,可以存储一个汉字。一个String,要看有几个字母或者几个汉字,一个英文字母就是一个字节,一个汉字就是两个字节,以此类推计算。 参考技术A 如果String串为纯英文,那么一个英文字母是一个字符,长度为1,占1个字节,不会出错,但如果String串中包含中文,一个中文汉字也是一个字符,长度为1,但是却占多个字节(具体占几个字节跟使用的编码有关),如果数据中包含中文,数据的长度就很有可能会超过数据库中对应字段的长度限制 参考技术B Java程序计算各种对象所占内存的大小的方法。

基类:

publicabstractclass SizeOf privatefinal Runtime s_runtime = Runtime.getRuntime(); protectedabstract Object newInstance(); publicint size() throws Exception runGC(); Object[] objects = new Object[count]; long heap1 = usedMemory(); for (int i = -1; i < count; ++i) Object object = null; object = newInstance(); objects[i] = object; object = null; runGC(); heap1 = usedMemory(); runGC(); long heap2 = usedMemory(); finalint size = Math.round(((float) (heap2 - heap1)) / count); for (int i = 0; i < count; ++i) objects[i] = null; privatevoid runGC() throws Exception for (int r = 0; r < 4; ++r) _runGC(); privatevoid _runGC() throws Exception long usedMem1 = usedMemory(); long usedMem2 = Long.MAX_VALUE; for (int i = 0; (usedMem1 < usedMem2) && (i < 500); ++i) s_runtime.runFinalization(); s_runtime.gc(); Thread.currentThread().yield(); usedMem2 = usedMem1; usedMem1 = usedMemory(); privatelong usedMemory() return s_runtime.totalMemory() - s_runtime.freeMemory();

子类:

publicclass SizeOfObject extends SizeOf protected Object newInstance() publicstaticvoid main(String[] args) throws Exception SizeOf sizeOf = new SizeOfObject(); System.out.println("所占内存:" + sizeOf.size() + "字节");

输出为:所占内存:8字节

Java 中的堆和栈


     Java把内存划分成两种:一种是栈内存,一种是堆内存。 
在Java中所有对象的存储空间都是在堆中分配的,但是这个对象的引用却是在堆栈中分配,也就是说在建立一个对象时从两个地方都分配内存,在堆中分配的内存实际建立这个对象,而在堆栈中分配的内存只是一个指向这个堆对象的指针(引用)而已。 
  当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间,当超过变量的作用域后,Java会自动释放掉为该变量所分配的内存空间,该内存空间可以立即被另作他用。 
  堆内存用来存放由new创建的对象和数组。 
  在堆中分配的内存,由Java虚拟机的自动垃圾回收器来管理。 
  在堆中产生了一个数组或对象后,还可以在栈中定义一个特殊的变量,让栈中这个变量的取值等于数组或对象在堆内存中的首地址,栈中的这个变量就成了数组或对象的引用变量 

                                                          
  引用变量就相当于是为数组或对象起的一个名称,以后就可以在程序中使用栈中的引用变量来访问堆中的数组或对象。 
  具体的说: 
  栈与堆都是Java用来在Ram中存放数据的地方。与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆。 
  Java的堆是一个运行时数据区,类的(对象从中分配空间。这些对象通过newnewarrayanewarraymultianewarray等指令建立,它们不需要程序代码来显式的释放。堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。 
  栈的优势是,存取速度比堆要快,仅次于寄存器,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。栈中主要存放一些基本类型的变量(,int, short, long, byte, float, double, boolean, char)和对象句柄。 
  栈有一个很重要的特殊性,就是存在栈中的数据可以共享。假设我们同时定义: 

  int a = 3; 

  int b = 3; 

  编译器先处理int a = 3;首先它会在栈中创建一个变量为a的引用,然后查找栈中是否有3这个值,如果没找到,就将3存放进来,然后将a指向3。接着处理int b = 3;在创建完b的引用变量后,因为在栈中已经有3这个值,便将b直接指向3。这样,就出现了ab同时均指向3的情况。这时,如果再令a=4;那么编译器会重新搜索栈中是否有4值,如果没有,则将4存放进来,并令a指向4;如果已经有了,则直接将a指向这个地址。因此a值的改变不会影响到b的值。要注意这种数据的共享与两个对象的引用同时指向一个对象的这种共享是不同的,因为这种情况a的修改并不会影响到b, 它是由编译器完成的,它有利于节省空间。而一个对象引用变量修改了这个对象的内部状态,会影响到另一个对象引用变量 。

从堆和栈的功能和作用来通俗的比较,堆主要用来存放对象的,栈主要是用来执行程序的.

引用:http://www.cnblogs.com/whgw/archive/2011/09/29/2194997.html

以上是关于JAVA里String数组在内存分配中分配的空间每个占几个字节?的主要内容,如果未能解决你的问题,请参考以下文章

Java 内存机制

Java 中的堆和栈

栈与堆

Java中堆内存与栈内存分配浅析

JAVA虚拟机内存分配与回收机制

栈与堆的区别