如果你用的是32位的系统,那么它只能支持到的内存容量最大是:325GB。
调虚拟内存,它看的不是那个内存,它的意思是说,将电脑硬盘中的某些容量来当作内存使用。比如说,你的电脑设为c,d,e,f四个分区。你可以在其中任何一个分区中设。最小值为:1024MB。最大值为:物理内存的15-2倍。当然你也可以设得更大,但是会浪费。1,linux下可以在/proc/cpuinfo中看到每个cpu的详细信息。但是对于双核的cpu,在cpuinfo中会看到两个cpu。常常会让人误以为是两个单核的cpu。
其实应该通过physical
processor
id来区分单核和双核。而physical
processor
id可以从cpuinfo或者dmesg中找到
flags
如果有
ht
说明支持超线程技术
判断物理cpu的个数可以查看physical
id
的值,相同则为同一个物理cpu
2,查看内存大小:
cat
/proc/meminfo
grep
memtotal
3,其他一些可以查看详细linux系统信息的命令和方法:
uname
-a
#
查看内核/ *** 作系统/cpu信息的linux系统信息命令
head
-n
1
/etc/issue
#
查看 *** 作系统版本,是数字1不是字母l
cat
/proc/cpuinfo
#
查看cpu信息的linux系统信息命令
hostname
#
查看计算机名的linux系统信息命令
lspci
-tv
#
列出所有pci设备
lsusb
-tv
#
列出所有usb设备的linux系统信息命令
lsmod
#
列出加载的内核模块
env
#
查看环境变量资源
free
-m
#
查看内存使用量和交换区使用量
df
-h
#
查看各分区使用情况
du
-sh
#
查看指定目录的大小
grep
memtotal
/proc/meminfo
#
查看内存总量
grep
memfree
/proc/meminfo
#
查看空闲内存量
uptime
#
查看系统运行时间、用户数、负载
cat
/proc/loadavg
#
查看系统负载磁盘和分区
mount
column
-t
#
查看挂接的分区状态
fdisk
-l
#
查看所有分区
swapon
-s
#
查看所有交换分区
hdparm
-i
/dev/hda
#
查看磁盘参数(仅适用于ide设备)
dmesg
grep
ide
#
查看启动时ide设备检测状况网络
ifconfig
#
查看所有网络接口的属性
iptables
-l
#
查看防火墙设置
route
-n
#
查看路由表
netstat
-lntp
#
查看所有监听端口
netstat
-antp
#
查看所有已经建立的连接
netstat
-s
#
查看网络统计信息进程
ps
-ef
#
查看所有进程
top
#
实时显示进程状态用户
w
#
查看活动用户
id
#
查看指定用户信息
last
#
查看用户登录日志
cut
-d:
-f1
/etc/passwd
#
查看系统所有用户
cut
-d:
-f1
/etc/group
#
查看系统所有组
crontab
-l
#
查看当前用户的计划任务服务
chkconfig
–list
#
列出所有系统服务
chkconfig
–list
grep
on
#
列出所有启动的系统服务程序
rpm
-qa
#
查看所有安装的软件包
cat
/proc/cpuinfo
:查看cpu相关参数的linux系统命令
cat
/proc/partitions
:查看linux硬盘和分区信息的系统信息命令
cat
/proc/meminfo
:查看linux系统内存信息的linux系统命令
cat
/proc/version
:查看版本,类似uname
-r
cat
/proc/ioports
:查看设备io端口
cat
/proc/interrupts
:查看中断
cat
/proc/pci
:查看pci设备的信息
cat
/proc/swaps
:查看所有swap分区的信息问题一:在电脑上怎么看电脑的物理内存是多少、虚拟内存是多少?、 点我的电脑-》属性-》高级-》性能里的设-》再点高级-》
就可以看到虚拟内存了。内存的话直接在属性那里就可以看到了。
问题二:什么叫物理内存?怎么知道自己电脑上的物理内存是多少? 物理内存当然就是你的实际内存虚拟内存。
右键点我的电脑-属性就可以看到你的内存大小。
虚拟内存调至物理内存的15倍较好。
在Windows2000(XP)目录下有一个名为pagefilesys的系统文件(Windows98下为Win386swp),它的大小经常自己发生变动,小的时候可能只有几十兆,大的时候则有数百兆,这种毫无规律的变化实在让很多人摸不着头脑。其实,pagefilesys是Windows下的一个虚拟内存,它的作用与物理内存基本相似,但它是作为物理内存的“后备力量”而存在的,也就是说,只有在物理内存已经不够使用的时候,它才会发挥作用。
1,虚拟内存的产生
我们都知道,虽然在运行速度上硬盘不如内存,但在容量上内存是无法与硬盘相提并论的。当运行一个程序需要大量数据、占用大量内存时,内存就会被“塞满”,并将那些暂时不用的数据放到硬盘中,而这些数据所占的空间就是虚拟内存。现在我们也明白为什么pagefilesys的大小会经常变化了。
内存在计算机中的作用很大,电脑中所有运行的程序都需要经过内存来执行,如果执行的程序很大或很多,就会导致内存消耗殆尽。为了解决这个问题,Windows中运用了虚拟内存技术,即拿出一部分硬盘空间来充当内存使用,当内存占用完时,电脑就会自动调用硬盘来充当内存,以缓解内存的紧张。举一个例子来说,如果电脑只有128MB物理内存的话,当读取一个容量为200MB的文件时,就必须要用到比较大的虚拟内存,文件被内存读取之后就会先储存到虚拟内存,等待内存把文件全部储存到虚拟内存之后,跟着就会把虚拟内里储存的文件释放到原来的安装目录里了。下面,就让我们一起来看看如何对虚拟内存进行设置吧。
2,虚拟内存的设置
对于虚拟内存主要设置两点,即内存大小和分页位置,内存大小就是设置虚拟内存最小为多少和最大为多少;而分页位置则是设置虚拟内存应使用那个分区中的硬盘空间。对于内存大小的设置,如何得到最小值和最大值呢?你可以通过下面的方法获得:选择“开始→程序→附件→系统工具→系统监视器”(如果系统工具中没有,可以通过“添加/删除程序”中的Windows安装程序进行安装)打开系统监视器,然后选择“编辑→添加项目”,在“类型”项中选择“内存管理程序”,在右侧的列表选择“交换文件大小”。这样随着你的 *** 作,会显示出交换文件值的波动情况,你可以把经常要使用到的程序打开,然后对它们进行使用,这时查看一下系统监视器中的表现值,由于用户每次使用电脑时的情况都不尽相同,因此,最好能够通过较长时间对交换文件进行监视来找出最符合您的交换文件的数值,这样才能保证系统性能稳定以及保持在最佳的状态。
找出最合适的范围值后,在设置虚拟内存时,用鼠标右键点击“我的电脑”,选择“属性”,d出系统属性窗口,选择“性能”标签,点击下面“虚拟内存”按钮,d出虚拟内存设置窗口,点击“用户自己指定虚拟内存设置”单选按钮,“硬盘”选较大剩余空间的分区,然后在“最小值”和“最大值”文本框中输入合适的范围值。如果您感觉使用系统监视器来获得最大和最小值有些麻烦的话,这里完全可以选择“让Windows管理虚拟内存设置”。
调整分页位置
Windows9x的虚拟内存分页位置,其实就是保存在C盘根目录下的一个虚拟内存文件(也称为交换文件)Win386swp,它的存放位置可以是任何一个分区,如果系统盘C容量有限,我们可以把Win386swp调到别的分区中,方法是在记事本中打开Systemini(C:Windows>>
问题三:怎么查看本机物理内存 方法如下:
方法一:在“计算机”上点击鼠标右键,左键单击底部“属性”。
方法二:攻手按住键盘Alt键不放,双击桌面上“计算机”图标。
物理内存是相对于逻辑内存而言的。物理内存指通过物理内存条而获得的内存空间,而逻辑内存则是指将硬盘的一块区域划分来作为内存。内存主要作用是在计算机运行时为 *** 作系统和各种程序提供临时储存。常见的物理内存规格有256M、512M、1G、2G等,现如今随着计算机硬件的发展,已经出现4G、8G甚至更高容量的内存规格。当物理内存不足时,可以用虚拟内存代替。在应用中,自然是顾名思义,物理上,真实存在的插在主板内存槽上的内存条的容量的大小。看计算机配置的时候,主要看的就是这个物理内存。
问题四:怎么查看自己电脑的内存大小? 1、你买的电脑实际内存都有数值的,一般是256M或512M,右键我的电脑――属性――就可看到。这个就叫物理内存。物理内存大小直接决定你电脑的运转速度,越大约好。与它相对的是虚拟内存,那是当物理内存不够时,暂时以硬盘作内存用,速度远不及物理内存(所以有时运行多了程序速度就慢了)。虚拟内存系统设有默认值,也可以自定义虚拟内存――当系统提示虚拟内存太小(程序占用内存太多)时。
2、右键“我的电脑”――属性――高级”――点“性能”下面的“设置”――点“高级”――点“虚拟内存”下方的“更改”――点“自定义大小”――根据你的实际情况设置最大值和最小值(我内存256,设的最小值512M,最大值1024M),也可以把它们都设成实际内存的2――3倍(假使实际内存=或小于256M)――3次确定――重启。
问题五:电脑的硬盘和物理内存的大小怎么看? 内存大小:右击“我的电脑”-》属性,里面就有硬盘大小:双击打开“我的电脑”,把里面那些本地磁盘(比如C:)的大小加起来,如果加起来的大小是 76xxG,那么你的硬盘大小应该憨比76xxG大一点的整数,也就是80G 影响网速主要是物理内存,因为物理内存剩余过小而网速过慢的,可以通过增加内存条,或者关闭某些不必要程序 系统运行迟缓的原因主要也是有可能物理内存,同样可以通过以上方法解决 当然,硬盘也可以间接影响到系统的网速和运行速度~~~
问题六:如何查看电脑已用内存 用在什么地方了? 把任务管理器调出来~
问题七:任务管理器中怎么查看电脑内存 性能-物理内存-总数
问题八:物理内存怎么看总数? 物理内存,指的是物理上安装的内存。显存是给显卡用的内存。
内存就是让你用的,75%说明你的内存没有浪费!!!
你原先用的那台一玩游戏就能涨到百分之90多就很慢很慢的,你知道为什么吗?因为那个老机子硬盘不给力,虚拟内存是位于硬盘上的,用于确保系统稳定运行,要频繁读写的,所以这个就要看硬盘的性能。你换个固态试试,占用95%以上依然顺畅无比!!!
你这个新机子的机械盘还是可以的,所以你内存占用高了并不会觉得卡。
不懂追问,满意请及时采纳~
问题九:怎么看电脑内存win7 桌面上找到计算机图标-按右键 -属性
新出来的页面上找到安装内存那项就是了
问题十:在电脑上怎么看电脑的物理内存是多少、虚拟内存是多少?、 点我的电脑-》属性-》高级-》性能里的设-》再点高级-》
就可以看到虚拟内存了。内存的话直接在属性那里就可以看到了。
linux中查看物理内存的命令是:dmidecode -t memory | grep Size。(如果没有安装dmidecode 需要先执行yum -y install dmidecode)
物理内存是没办法配置的,只能配置虚拟内存,在Linux系统即Swap分区,查看Swap分区的命令是:free -k 或者 free -m。m代表以MB为单位,k代表以KB为单位。
扩展资料
dmidecode命令介绍
使用方法:
dmidecode [OPTIONS]
参数介绍:
-d, --dev-mem FILE 从设备文件读取内存(默认: /dev/mem)
-h, --help 显示此帮助文本并退出。
-q, --quiet 减少详细输出。
-t, --type TYPE 仅显示给定类型的条目。
-V, --version 查看版本号。
2、打开存储选项后,在里面就会看到你手机自带内存、内置内存、SD卡或者TF卡的内存容量了,然后互相进行调整,安装软件。
查看运行内存
1,查看运行内存的方法很简单的,我们同样是打开手机的设置功能,然后在里面找到应用这个选项,因为运行内存就是看你运行程序所占的内存,和电脑的内存条一样,
2,打开应用功能后,最下面可以看到一个进度条,这个就代表了你目前运行内存的使用情况,如果占用过多,就关闭一些程序吧。
扩展资料
广义的手机系统内存分为“手机运行内存”及“手机非运行内存”。手机的“运行内存”相当于电脑的内存(或者叫内存条); 而手机的“非运行内存”,即手机的ROM和硬盘,是机身内部存储器(简称机身内存),相当于电脑的硬盘。手机“运行内存”越大,手机能运行多个程序且流畅;手机“非运行内存”越大,就像硬盘越大,能存放更多的数据。
定义:
手机系统内存是指手机运行程序时使用的内存(即运行内存),只能临时存储数据,用于与CPU交换高速缓存数据,但是随机存储器(RAM)本身不能用于长期存储数据。
而另一个广义的手机系统内存是用来存储东西的内置存储器(通常被简称成了“内存”),即机身内存,安卓手机系统占用一部分,其它安装程序也会占用一部分。
就像8G的MP4一样,它拥有8G的存储空间。用电脑比喻的话,手机系统内存就是电脑的内存(内存条);另一个广义的手机系统内存就是电脑的硬盘(一个只有C盘的单分区硬盘)。
拥有更大的系统内存内存的话手机可以打开更多的程序或者占用更大资源的程序,在手机系统内存足够的情况下并不能提升运行程序的速度,只能说更大的运行内存能更好的保证手机的正常运行。
Java内存分配与管理是Java的核心技术之一,一般Java在内存分配时会涉及到以下区域:
◆寄存器:我们在程序中无法控制
◆栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中
◆堆:存放用new产生的数据
◆静态域:存放在对象中用static定义的静态成员
◆常量池:存放常量
◆非RAM存储:硬盘等永久存储空间
Java内存分配中的栈
在函数中定义的一些基本类型的变量数据和对象的引用变量都在函数的栈内存中分配。
当在一段代码块定义一个变量时,Java就在栈中 为这个变量分配内存空间,当该变量退出该作用域后,Java会自动释放掉为该变量所分配的内存空间,该内存空间可以立即被另作他用。
Java内存分配中的堆
堆内存用来存放由new创建的对象和数组。 在堆中分配的内存,由Java虚拟机的自动垃圾回收器来管理。
在堆中产生了一个数组或对象后,还可以 在栈中定义一个特殊的变量,让栈中这个变量的取值等于数组或对象在堆内存中的首地址,栈中的这个变量就成了数组或对象的引用变量。 引用变量就相当于是 为数组或对象起的一个名称,以后就可以在程序中使用栈中的引用变量来访问堆中的数组或对象。引用变量就相当于是为数组或者对象起的一个名称。
引用变量是普通的变量,定义时在栈中分配,引用变量在程序运行到其作用域之外后被释放。而数组和对象本身在堆中分配,即使程序 运行到使用 new 产生数组或者对象的语句所在的代码块之外,数组和对象本身占据的内存不会被释放,数组和对象在没有引用变量指向它的时候,才变为垃圾,不能在被使用,但仍 然占据内存空间不放,在随后的一个不确定的时间被垃圾回收器收走(释放掉)。这也是 Java 比较占内存的原因。
实际上,栈中的变量指向堆内存中的变量,这就是Java中的指针!
常量池 (constant pool)
常量池指的是在编译期被确定,并被保存在已编译的class文件中的一些数据。除了包含代码中所定义的各种基本类型(如int、long等等)和对象型(如String及数组)的常量值(final)还包含一些以文本形式出现的符号引用,比如:
◆类和接口的全限定名;
◆字段的名称和描述符;
◆方法和名称和描述符。
虚拟机必须为每个被装载的类型维护一个常量池。常量池就是该类型所用到常量的一个有序集和,包括直接常量(string,integer和 floating point常量)和对其他类型,字段和方法的符号引用。
对于String常量,它的值是在常量池中的。而JVM中的常量池在内存当中是以表的形式存在的, 对于String类型,有一张固定长度的CONSTANT_String_info表用来存储文字字符串值,注意:该表只存储文字字符串值,不存储符号引 用。说到这里,对常量池中的字符串值的存储位置应该有一个比较明了的理解了。
在程序执行的时候,常量池 会储存在Method Area,而不是堆中。
堆与栈
Java的堆是一个运行时数据区,类的(对象从中分配空间。这些对象通过new、newarray、 anewarray和multianewarray等指令建立,它们不需要程序代码来显式的释放。堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存 大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态 分配内存,存取速度较慢。
栈的优势是,存取速度比堆要快,仅次于寄存器,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是 确定的,缺乏灵活性。栈中主要存放一些基本类型的变量数据(int, short, long, byte, float, double, boolean, char)和对象句柄(引用)。
栈有一个很重要的特殊性,就是存在栈中的数据可以共享。假设我们同时定义:
1 int a = 3;
2 int b = 3;
编译器先处理int a = 3;首先它会在栈中创建一个变量为a的引用,然后查找栈中是否有3这个值,如果没找到,就将3存放进来,然后将a指向3。接着处理int b = 3;在创建完b的引用变量后,因为在栈中已经有3这个值,便将b直接指向3。这样,就出现了a与b同时均指向3的情况。
这时,如果再令 a=4;那么编译器会重新搜索栈中是否有4值,如果没有,则将4存放进来,并令a指向4;如果已经有了,则直接将a指向这个地址。因此a值的改变不会影响 到b的值。
要注意这种数据的共享与两个对象的引用同时指向一个对象的这种共享是不同的,因为这种情况a的修改并不会影响到b, 它是由编译器完成的,它有利于节省空间。而一个对象引用变量修改了这个对象的内部状态,会影响到另一个对象引用变量。
String是一个特殊的包装类数据。可以用:
String str = new String("abc");
String str = "abc";
两种的形式来创建,第一种是用new()来新建对象的,它会在存放于堆中。每调用一次就会创建一个新的对象。而第二种是先在栈中创建一个对String类的对象引用变量str,然后通过符号引用去字符串常量池 里找有没有"abc",如果没有,则将"abc"存放进字符串常量池 ,并令str指向”abc”,如果已经有”abc” 则直接令str指向“abc”。
比较类里面的数值是否相等时,用equals()方法;当测试两个包装类的引用是否指向同一个对象时,用==,下面用例子说明上面的理论。
1.String str1 = "abc";
2.String str2 = "abc";
3.Systemoutprintln(str1==str2); //true
可以看出str1和str2是指向同一个对象的。
1.String str1 =new String ("abc");
2.String str2 =new String ("abc");
3.Systemoutprintln(str1==str2); // false
用new的方式是生成不同的对象。每一次生成一个。
因此用第二种方式创建多个”abc”字符串,在内存中 其实只存在一个对象而已 这种写法有利与节省内存空间 同时它可以在一定程度上提高程序的运行速度,因为JVM会自动根据栈中数据的实际情况来决定是否有必要创建新对象。而对于String str = new String("abc");的代码,则一概在堆中创建新对象,而不管其字符串值是否相等,是否有必要创建新对象,从而加重了程序的负担。
另 一方面, 要注意: 我们在使用诸如String str = "abc";的格式定义类时,总是想当然地认为,创建了String类的对象str。担心陷阱!对象可能并没有被创建!而可能只是指向一个先前已经创建的 对象。只有通过new()方法才能保证每次都创建一个新的对象。
由于String类的immutable性质,当String变量需要经常变换 其值时,应该考虑使用StringBuffer类,以提高程序效率。
1 首先String不属于8种基本数据类型,String是一个对象。因为对象的默认值是null,所以String的默认值也是null;但它又是一种特殊的对象,有其它对象没有的一些特性。
2 new String()和new String(”")都是申明一个新的空字符串,是空串不是null;
3 String str=”kvill”;String str=new String (”kvill”)的区别
示例:
1.String s0="kvill";
2.String s1="kvill";
3.String s2="kv" + "ill";
4.Systemoutprintln( s0==s1 );
5.Systemoutprintln( s0==s2 );
结果为:
true
true
首先,我们要知结果为道Java 会确保一个字符串常量只有一个拷贝。
因为例子中的 s0和s1中的”kvill”都是字符串常量,它们在编译期就被确定了,所以s0==s1为true;而”kv”和”ill”也都是字符串常量,当一个字 符串由多个字符串常量连接而成时,它自己肯定也是字符串常量,所以s2也同样在编译期就被解析为一个字符串常量,所以s2也是常量池中” kvill”的一个引用。所以我们得出s0==s1==s2;用new String() 创建的字符串不是常量,不能在编译期就确定,所以new String() 创建的字符串不放入常量池中,它们有自己的地址空间。
示例:
6.String s0="kvill";
7.String s1=new String("kvill");
8.String s2="kv" + new String("ill");
9.Systemoutprintln( s0==s1 );
10.Systemoutprintln( s0==s2 );
11.Systemoutprintln( s1==s2 );
结果为:
false
false
false
例2中s0还是常量池 中"kvill”的应用,s1因为无法在编译期确定,所以是运行时创建的新对象”kvill”的引用,s2因为有后半部分 new String(”ill”)所以也无法在编译期确定,所以也是一个新创建对象”kvill”的应用;明白了这些也就知道为何得出此结果了。
4 Stringintern():
再补充介绍一点:存在于class文件中的常量池,在运行期被JVM装载,并且可以扩充。String的 intern()方法就是扩充常量池的 一个方法;当一个String实例str调用intern()方法时,Java 查找常量池中 是否有相同Unicode的字符串常量,如果有,则返回其的引用,如果没有,则在常 量池中增加一个Unicode等于str的字符串并返回它的引用;看示例就清楚了
示例:
1.String s0= "kvill";
2.String s1=new String("kvill");
3.String s2=new String("kvill");
4.Systemoutprintln( s0==s1 );
5.Systemoutprintln( "" );
6.s1intern();
7.s2=s2intern(); //把常量池中"kvill"的引用赋给s2
8.Systemoutprintln( s0==s1);
9.Systemoutprintln( s0==s1intern() );
10.Systemoutprintln( s0==s2 );
结果为:
false
false //虽然执行了s1intern(),但它的返回值没有赋给s1
true //说明s1intern()返回的是常量池中"kvill"的引用
true
最后我再破除一个错误的理解:有人说,“使用 Stringintern() 方法则可以将一个 String 类的保存到一个全局 String 表中 ,如果具有相同值的 Unicode 字符串已经在这个表中,那么该方法返回表中已有字符串的地址,如果在表中没有相同值的字符串,则将自己的地址注册到表中”如果我把他说的这个全局的 String 表理解为常量池的话,他的最后一句话,”如果在表中没有相同值的字符串,则将自己的地址注册到表中”是错的:
示例:
1.String s1=new String("kvill");
2.String s2=s1intern();
3.Systemoutprintln( s1==s1intern() );
4.Systemoutprintln( s1+" "+s2 );
5.Systemoutprintln( s2==s1intern() );
结果:
1. false
2. kvill kvill
3. true
在这个类中我们没有声名一个”kvill”常量,所以常量池中一开始是没有”kvill”的,当我们调用s1intern()后就在常量池中新添加了一 个”kvill”常量,原来的不在常量池中的”kvill”仍然存在,也就不是“将自己的地址注册到常量池中”了。
s1==s1intern() 为false说明原来的”kvill”仍然存在;s2现在为常量池中”kvill”的地址,所以有s2==s1intern()为true。
5 关于equals()和==:
这个对于String简单来说就是比较两字符串的Unicode序列是否相当,如果相等返回true;而==是 比较两字符串的地址是否相同,也就是是否是同一个字符串的引用。
6 关于String是不可变的
这一说又要说很多,大家只 要知道String的实例一旦生成就不会再改变了,比如说:String str=”kv”+”ill”+” “+”ans”; 就是有4个字符串常量,首先”kv”和”ill”生成了”kvill”存在内存中,然后”kvill”又和” ” 生成 “kvill “存在内存中,最后又和生成了”kvill ans”;并把这个字符串的地址赋给了str,就是因为String的”不可变”产生了很多临时变量,这也就是为什么建议用StringBuffer的原 因了,因为StringBuffer是可改变的。
下面是一些String相关的常见问题:
String中的final用法和理解
final StringBuffer a = new StringBuffer("111");
final StringBuffer b = new StringBuffer("222");
a=b;//此句编译不通过
final StringBuffer a = new StringBuffer("111");
aappend("222");// 编译通过
可见,final只对引用的"值"(即内存地址)有效,它迫使引用只能指向初始指向的那个对象,改变它的指向会导致编译期错误。至于它所指向的对象 的变化,final是不负责的。
String常量池问题的几个例子
下面是几个常见例子的比较分析和理解:
String a = "a1";
String b = "a" + 1;
Systemoutprintln((a == b)); //result = true
String a = "atrue";
String b = "a" + "true";
Systemoutprintln((a == b)); //result = true
String a = "a34";
String b = "a" + 34;
Systemoutprintln((a == b)); //result = true
分析:JVM对于字符串常量的"+"号连接,将程序编译期,JVM就将常量字符串的"+"连接优化为连接后的值,拿"a" + 1来说,经编译器优化后在class中就已经是a1。在编译期其字符串常量的值就确定下来,故上面程序最终的结果都为true。
String a = "ab";
String bb = "b";
String b = "a" + bb;
Systemoutprintln((a == b)); //result = false
分析:JVM对于字符串引用,由于在字符串的"+"连接中,有字符串引用存在,而引用的值在程序编译期是无法确定的,即"a" + bb无法被编译器优化,只有在程序运行期来动态分配并将连接后的新地址赋给b。所以上面程序的结果也就为false。
String a = "ab";
final String bb = "b";
String b = "a" + bb;
Systemoutprintln((a == b)); //result = true
分析:和[3]中唯一不同的是bb字符串加了final修饰,对于final修饰的变量,它在编译时被解析为常量值的一个本地拷贝存储到自己的常量 池中或嵌入到它的字节码流中。所以此时的"a" + bb和"a" + "b"效果是一样的。故上面程序的结果为true。
String a = "ab";
final String bb = getBB();
String b = "a" + bb;
Systemoutprintln((a == b)); //result = false
private static String getBB() {
return "b";
}
分析:JVM对于字符串引用bb,它的值在编译期无法确定,只有在程序运行期调用方法后,将方法的返回值和"a"来动态连接并分配地址为b,故上面 程序的结果为false。
通过上面4个例子可以得出得知:
String s = "a" + "b" + "c";
就等价于String s = "abc";
String a = "a";
String b = "b";
String c = "c";
String s = a + b + c;
这个就不一样了,最终结果等于:
1.StringBuffer temp = new StringBuffer();
2.tempappend(a)append(b)append(c);
3.String s = temptoString();
由上面的分析结果,可就不难推断出String 采用连接运算符(+)效率低下原因分析,形如这样的代码:
public class Test {
public static void main(String args[]) {
String s = null;
for(int i = 0; i < 100; i++) {
s += "a";
}
}
}
每做一次 + 就产生个StringBuilder对象,然后append后就扔掉。下次循环再到达时重新产生个StringBuilder对象,然后 append 字符串,如此循环直至结束。如果我们直接采用 StringBuilder 对象进行 append 的话,我们可以节省 N - 1 次创建和销毁对象的时间。所以对于在循环中要进行字符串连接的应用,一般都是用StringBuffer或StringBulider对象来进行 append *** 作。
String对象的intern方法理解和分析:
1.public class Test4 {
2. private static String a = "ab";
3. public static void main(String[] args){
4. String s1 = "a";
5. String s2 = "b";
6. String s = s1 + s2;
7. Systemoutprintln(s == a);//false
8. Systemoutprintln(sintern() == a);//true
9. }
10.}
这里用到Java里面是一个常量池的问题。对于s1+s2 *** 作,其实是在堆里面重新创建了一个新的对象,s保存的是这个新对象在堆空间的的内容,所 以s与a的值是不相等的。而当调用sintern()方法,却可以返回s在常量池中的地址值,因为a的值存储在常量池中,故sintern和a的值相等。
总结
栈中用来存放一些原始数据类型的局部变量数据和对象的引用(String,数组对象等等)但不存放对象内容
堆中存放使用new关键字创建的对象
字符串是一个特殊包装类,其引用是存放在栈里的,而对象内容必须根据创建方式不同定(常量池和堆)有的是编译期就已经创建好,存放在字符串常 量池中,而有的是运行时才被创建使用new关键字,存放在堆中。
C++程序的内纯格局通常分为4个区:1数据区(Data Area)
2代码区(Code Area)
3栈区(Stack Area)
4堆区(即自由存储区)(Heap Area)
全局变量、静态变量、常量存放在数据区,所有类成员函数和非成员函数代码存放在代码区,为运行函数而分配的局部变量、函数参数、返回数据、返回地址等存放在栈区,余下的空间为堆区。
因为堆是有限的,它可能变得拥挤,如果堆中没有足够的自由空间以满足内存的需要时,那么此需要失败,并且返回一个空指针。因此,必须在使用NEW生成的指针之前进行检查,方法如下:
C++代码
HeapClass pa1 , pa2;
pa1 = new HeapClass(4); // 分配空间
pa2 = new HeapClass (); // 分配空间
if(!pa1 || !pa2){ // 检查空间
cout<<"out of Memory"<<endl;
return;
}
HeapClass pa1 , pa2;
pa1 = new HeapClass(4); // 分配空间
pa2 = new HeapClass (); // 分配空间
if(!pa1 || !pa2){ // 检查空间
cout<<"out of Memory"<<endl;
return;
}
一般来说,堆空间相对其他内存空间比较空闲,随要随拿,给程序运行带来了较大的自由度,但是管理堆区是一件十分复杂的工作,频繁地分配(NEW)和释放(DELETE)不同大小的堆空间将会产生堆内碎块。使用堆空间往往由于:
直到运行时才能知道需要多少对象空间;
不知道对象的生存期到底有多长;
直到运行时才知道一个对象需要多少内存空间;
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)