java虚拟机内存(JAVA虚拟机内存分配与回收机制)
本文目录
- JAVA虚拟机内存分配与回收机制
- java编程内存管理需要注意的问题
- myeclipse 8.5 java工程怎么修改虚拟机的内存
- ubuntu下java虚拟机内存设置
- 关于设置Java虚拟机(JVM)的内存问题
- 怎样修改java虚拟机的内存大小
- 如何修改java虚拟机内存
JAVA虚拟机内存分配与回收机制
Java 中的堆和栈简单的说:Java把内存划分成两种:一种是栈内存,一种是堆内存。 在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配。 当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间,当超过变量的作用域后,Java会自动释放掉为该变量所分配的内存空间,该内存空间可以立即被另作他用。 堆内存用来存放由new创建的对象和数组。 在堆中分配的内存,由Java虚拟机的自动垃圾回收器来管理。 在堆中产生了一个数组或对象后,还可以在栈中定义一个特殊的变量,让栈中这个变量的取值等于数组或对象在堆内存中的首地址,栈中的这个变量就成了数组或对象的引用变量。 引用变量就相当于是为数组或对象起的一个名称,以后就可以在程序中使用栈中的引用变量来访问堆中的数组或对象。 具体的说:栈与堆都是Java用来在Ram中存放数据的地方。与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆。 Java的堆是一个运行时数据区,类的(对象从中分配空间。这些对象通过new、newarray、anewarray和multianewarray等 指令建立,它们不需要程序代码来显式的释放。堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时 动态分配内存的,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。这样,就出现了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()方法;当测试两个包装类的引用是否指向同一个对象时,用==,下面用例子说明上面的理论。 String str1 = "abc"; String str2 = "abc"; System.out.println(str1==str2); //true 可以看出str1和str2是指向同一个对象的。 String str1 =new String ("abc"); String str2 =new String ("abc"); System.out.println(str1==str2); // false 用new的方式是生成不同的对象。每一次生成一个。 因此用第二种方式创建多个”abc”字符串,在内存中其实只存在一个对象而已. 这种写法有利与节省内存空间. 同时它可以在一定程度上提高程序的运行速度,因为JVM会自动根据栈中数据的实际情况来决定是否有必要创建新对象。而对于String str = new String("abc");的代码,则一概在堆中创建新对象,而不管其字符串值是否相等,是否有必要创建新对象,从而加重了程序的负担。 另一方面, 要注意: 我们在使用诸如String str = "abc";的格式定义类时,总是想当然地认为,创建了String类的对象str。担心陷阱!对象可能并没有被创建!而可能只是指向一个先前已经创建的 对象。只有通过new()方法才能保证每次都创建一个新的对象。 由于String类的immutable性质,当String变量需要经常变换其值时,应该考虑使用StringBuffer类,以提高程序效率。java中内存分配策略及堆和栈的比较 2.1 内存分配策略 按照编译原理的观点,程序运行时的内存分配有三种策略,分别是静态的,栈式的,和堆式的. 静态存储分配是指在编译时就能确定每个数据目标在运行时刻的存储空间需求,因而在编译时就可以给他们分配固定的内存空间.这种分配策略要求程序代码中不允 许有可变数据结构(比如可变数组)的存在,也不允许有嵌套或者递归的结构出现,因为它们都会导致编译程序无法计算准确的存储空间需求. 栈式存储分配也可称为动态存储分配,是由一个类似于堆栈的运行栈来实现的.和静态存储分配相反,在栈式存储方案中,程序对数据区的需求在编译时是完全未知 的,只有到运行的时候才能够知道,但是规定在运行中进入一个程序模块时,必须知道该程序模块所需的数据区大小才能够为其分配内存.和我们在数据结构所熟知 的栈一样,栈式存储分配按照先进后出的原则进行分配。 静态存储分配要求在编译时能知道所有变量的存储要求,栈式存储分配要求在过程的入口处必须知道所有的存储要求,而堆式存储分配则专门负责在编译时或运行时 模块入口处都无法确定存储要求的数据结构的内存分配,比如可变长度串和对象实例.堆由大片的可利用块或空闲块组成,堆中的内存可以按照任意顺序分配和释 放. 2.2 堆和栈的比较 上面的定义从编译原理的教材中总结而来,除静态存储分配之外,都显得很呆板和难以理解,下面撇开静态存储分配,集中比较堆和栈: 从堆和栈的功能和作用来通俗的比较,堆主要用来存放对象的,栈主要是用来执行程序的.而这种不同又主要是由于堆和栈的特点决定的: 在编程中,例如C/C++中,所有的方法调用都是通过栈来进行的,所有的局部变量,形式参数都是从栈中分配内存空间的。实际上也不是什么分配,只是从栈顶 向上用就行,就好像工厂中的传送带(conveyor belt)一样,Stack Pointer会自动指引你到放东西的位置,你所要做的只是把东西放下来就行.退出函数的时候,修改栈指针就可以把栈中的内容销毁.这样的模式速度最快, 当然要用来运行程序了.需要注意的是,在分配的时候,比如为一个即将要调用的程序模块分配数据区时,应事先知道这个数据区的大小,也就说是虽然分配是在程 序运行时进行的,但是分配的大小多少是确定的,不变的,而这个"大小多少"是在编译时确定的,不是在运行时. 堆是应用程序在运行的时候请求操作系统分配给自己内存,由于从操作系统管理的内存分配,所以在分配和销毁时都要占用时间,因此用堆的效率非常低.但是堆的 优点在于,编译器不必知道要从堆里分配多少存储空间,也不必知道存储的数据要在堆里停留多长的时间,因此,用堆保存数据时会得到更大的灵活性。事实上,面 向对象的多态性,堆内存分配是必不可少的,因为多态变量所需的存储空间只有在运行时创建了对象之后才能确定.在C++中,要求创建一个对象时,只需用 new命令编制相关的代码即可。执行这些代码时,会在堆里自动进行数据的保存.当然,为达到这种灵活性,必然会付出一定的代价:在堆里分配存储空间时会花 掉更长的时间!这也正是导致我们刚才所说的效率低的原因,看来列宁同志说的好,人的优点往往也是人的缺点,人的缺点往往也是人的优点(晕~). 2.3 JVM中的堆和栈 JVM是基于堆栈的虚拟机.JVM为每个新创建的线程都分配一个堆栈.也就是说,对于一个Java程序来说,它的运行就是通过对堆栈的操作来完成的。堆栈以帧为单位保存线程的状态。JVM对堆栈只进行两种操作:以帧为单位的压栈和出栈操作。 我们知道,某个线程正在执行的方法称为此线程的当前方法.我们可能不知道,当前方法使用的帧称为当前帧。当线程激活一个Java方法,JVM就会在线程的 Java堆栈里新压入一个帧。这个帧自然成为了当前帧.在此方法执行期间,这个帧将用来保存参数,局部变量,中间计算过程和其他数据.这个帧在这里和编译 原理中的活动纪录的概念是差不多的. 从Java的这种分配机制来看,堆栈又可以这样理解:堆栈(Stack)是操作系统在建立某个进程时或者线程(在支持多线程的操作系统中是线程)为这个线程建立的存储区域,该区域具有先进后出的特性。 每一个Java应用都唯一对应一个JVM实例,每一个实例唯一对应一个堆。应用程序在运行中所创建的所有类实例或数组都放在这个堆中,并由应用所有的线程 共享.跟C/C++不同,Java中分配堆内存是自动初始化的。Java中所有对象的存储空间都是在堆中分配的,但是这个对象的引用却是在堆栈中分配,也 就是说在建立一个对象时从两个地方都分配内存,在堆中分配的内存实际建立这个对象,而在堆栈中分配的内存只是一个指向这个堆对象的指针(引用)而已。***隐藏网址***呵呵,在看到你的问题前10分钟才看的这个文章...
java编程内存管理需要注意的问题
大家在进行程序系统维护的时候是否因为java编程的内存管理问题而无法快速解决导致系统出错呢?下面我们就一起来了解和学习一下,关于java编程内存管理都有哪些知识点。
程序计数器(了解)
程序计数器,可以看做是当前线程所执行的字节码的行号指示器。在虚拟机的概念模型里,字节码解释器工作就是通过改变程序计数器的值来选择下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都要依赖这个计数器来完成。
Java虚拟机栈(了解)
Java虚拟机栈也是线程私有的,它的生命周期与线程相同。虚拟机栈描述的是Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧用于存储局部变量表、操作数栈、动态链表、方法出口信息等。每一个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。
局部变量表中存放了编译器可知的各种基本数据类型(boolean、byte、char、short、int、float、long、double)、对象引用和returnAddress类型(指向了一条字节码指令的地址)。
如果扩展时无法申请到足够的内存,就会抛出OutOfMemoryError异常。
本地方法栈(了解)
本地方法栈与虚拟机的作用相似,不同之处在于虚拟机栈为虚拟机执行的Java方法服务,而本地方法栈则为虚拟机使用到的Native方法服务。有的虚拟机直接把本地方法栈和虚拟机栈合二为一。
会抛出stackOverflowError和OutOfMemoryError异常。
Java堆
堆内存用来存放由new创建的对象实例和数组。(重点)
Java堆是所有线程共享的一块内存区域,在虚拟机启动时创建,此内存区域的目的就是存放对象实例。
Java堆是垃圾收集器管理的主要区域。java课程培训机构发现由于现在收集器基本采用分代回收算法,所以Java堆还可细分为:新生代和老年代。从内存分配的角度来看,线程共享的Java堆中可能划分出多个线程私有的分配缓冲区(TLAB)。
myeclipse 8.5 java工程怎么修改虚拟机的内存
修改虚拟内存步骤如下:1、设置Default VM Arguments 在myEclipse中,打开Windows-》 Preferences-》Java-》Installed JREs-》点击正在使用的JDK-》Edit-》Default VM Arguments文本框中输入:-Xms64m -Xmx256m 2、如果是web工程还报内存溢出,可能就要设置tomcat内存。(1)tomcat的安装根目录%tomcat%bin/catalina.bat文件,SET JAVA_OPTS 一行;(2)myeclipse配置web服务器配置 Window—Preferences—Myeclipse—Servers—tomcat 5.x—JDK的Optional Java VM arguments配置为:-Xms256m -Xmx512m -XX:MaxNewSize=256m -XX:MaxPermSize=256m。
ubuntu下java虚拟机内存设置
ubuntu下java虚拟机内存设置是物理内存容量的1.5到3倍。根据查询相关资料信息显示,ubuntu下java虚拟机内存理设置虚拟内存虚拟内存的设定主要根据你的物理内存大小和电脑的用途来设定,设为物理内存容量的1.5到3倍。
关于设置Java虚拟机(JVM)的内存问题
最近做毕设时 遇到了一点小问题 在解析dblp xml文件时(该文件很大 最新版本为 MB) 老是报错
java lang OutOfMemoryError: Java heap space
最后通过查资料才知道 这是由于JVM堆内存不足造成的 JVM在启动动的时候一般会设置JVM Heap的值
其初始空间(即 Xms)是物理内存的 / 最大空间( Xmx)不可超过物理内存 在JVM中如果 %的时间是用于GC 且可用的Heap size 不足 %的时候将抛出此异常信息 出现这种问题可以通过修改JVM heap大小解决
如
点击(此处)折叠或打开
java Xms M Xmx M className
以上设置JVM初始化堆内存为 M 最大可用堆内存为 M
( )在命令行中设置的方法就如上面所述
( )在Eclipse中可以这样设置
在eclipse的 Run 》Run Configurations 》Arguments下的VM Arguments中设置
Xms M Xmx M
另外可以使用 java X查看其它JVM参数情况
点击(此处)折叠或打开
D:\work》java X
Xmixed mixed mode execution (default)
Xint interpreted mode execution only
Xbootclasspath:《directories and zip/jar files separated by ;》
set search path for bootstrap classes and resources
Xbootclasspath/a:《directories and zip/jar files separated by ;》
append to end of bootstrap class path
Xbootclasspath/p:《directories and zip/jar files separated by ;》
prepend in front of bootstrap class path
Xnoclassgc disable class garbage collection
Xincgc enable incremental garbage collection
Xloggc:《file》 log GC status to a file with time stamps
Xbatch disable background pilation
Xms《size》 set initial Java heap size
Xmx《size》 set maximum Java heap size
Xss《size》 set java thread stack size
Xprof output cpu profiling data
Xfuture enable strictest checks anticipating future default
Xrs reduce use of OS signals by Java/VM (see documentation)
Xcheck:jni perform additional checks for JNI functions
Xshare:off do not attempt to use shared class data
Xshare:auto use shared class data if possible (default)
Xshare:on require using shared class data otherwise fail
The X options are non standard and subject to change without notice
可以通过java lang Runtime的一些方法查看jvm的内存使用情况
点击(此处)折叠或打开
System out println( Total Memory: + Runtime getRuntime() totalMemory() / ( * + MB )
System out println( Free Memory: + Runtime getRuntime() freeMemory() / ( * ) + MB )
System out println( Max Memory: + Runtime getRuntime() maxMemory() / ( * ) + MB )
maxMemory()这个方法返回的是java虚拟机(这个进程)能构从操作系统那里挖到的最大的内存 以字节为单位
totalMemory()这个方法返回的是java虚拟机现在已经从操作系统那里挖过来的内存大小 也就是java虚拟机这个进程当时所占用的所有内存
freeMemory为当前jvm中没有使用的内存
附 jvm参数说明 (转自)
server:一定要作为第一个参数 在多个CPU时性能佳
Xms java Heap初始大小 默认是物理内存的 /
Xmx java heap最大值 建议均设为物理内存的一半 不可超过物理内存
XX:PermSize:设定内存的永久保存区初始大小 缺省值为 M (我用visualvm exe查看的)
XX:MaxPermSize:设定内存的永久保存区最大 大小 缺省值为 M (我用visualvm exe查看的)
XX:SurvivorRatio= :生还者池的大小 默认是 如果垃圾回收变成了瓶颈 您可以尝试定制生成池设置
XX:NewSize: 新生成的池的初始大小 缺省值为 M
XX:MaxNewSize: 新生成的池的最大大小 缺省值为 M
如果 JVM 的堆大小大于 GB 则应该使用值 XX:newSize= m XX:MaxNewSize= m XX:SurvivorRatio= 或者将堆的总大小的 % 到 % 分配给新生成的池 调大新对象区 减少Full GC次数
+XX:AggressiveHeap 会使得 Xms没有意义 这个参数让jvm忽略Xmx参数 疯狂地吃完一个G物理内存 再吃尽一个G的swap
Xss 每个线程的Stack大小 Xss 这使得JBoss每增加一个线程(thread)就会立即消耗 M内存 而最佳值应该是 K 默认值好像是 k
verbose:gc 现实垃圾收集信息
Xloggc:gc log 指定垃圾收集日志文件
Xmn young generation的heap大小 一般设置为Xmx的 分之一
XX:+UseParNewGC 缩短minor收集的时间
XX:+UseConcMarkSweepGC 缩短major收集的时间 此选项在Heap Size 比较大而且Major收集时间较长的情况下使用更合适
XX:userParNewGC 可用来设置并行收集【多CPU】
XX:ParallelGCThreads 可用来增加并行度【多CPU】
lishixinzhi/Article/program/Java/hx/201311/26103
怎样修改java虚拟机的内存大小
修改java虚拟机的内存大小:
Window--Preferences如图下所示
在下图所示左边树双击JAVA,再双击Installed JRES,如图所示
在右边选择前面有对勾的JRE,再单击右边的“Edit”按钮,如图所示
出现一个 Edit JRE 的对话框,在下图所示的Default VM Arguments: 框中输入 -Xms128m -Xmx512m ,这样设置Java拟虚机内存使用最小是128M,最大是512M,再单击“OK”关闭 Edit JRE 对话框,再单击“OK”关闭 Preferences对话框,Eclipse的速度就有所提高了
如何修改java虚拟机内存
一、设置JVM内存设置1. 设置JVM内存的参数有四个:-Xmx Java Heap最大值,默认值为物理内存的1/4,最佳设值应该视物理内存大小及计算机内其他内存开销而定;-Xms Java Heap初始值,Server端JVM最好将-Xms和-Xmx设为相同值,开发测试机JVM可以保留默认值;-Xmn Java Heap Young区大小,不熟悉最好保留默认值;-Xss 每个线程的Stack大小,不熟悉最好保留默认值;2. 如何设置JVM内存分配:(1)当在命令提示符下启动并使用JVM时(只对当前运行的类Test生效):java -Xmx128m -Xms64m -Xmn32m -Xss16m Test(2)当在集成开发环境下(如eclipse)启动并使用JVM时:a. 在eclipse根目录下打开eclipse.ini,默认内容为(这里设置的是运行当前开发工具的JVM内存分配):-vmargs -Xms40m -Xmx256m -vmargs表示以下为虚拟机设置参数,可修改其中的参数值,也可添加-Xmn,-Xss,另外,eclipse.ini内还可以设置非堆内存,如:-XX:PermSize=56m,-XX:MaxPermSize=128m。此处设置的参数值可以通过以下配置在开发工具的状态栏显示:在eclipse根目录下创建文件options,文件内容为:org.eclipse.ui/perf/showHeapStatus=true修改eclipse根目录下的eclipse.ini文件,在开头处添加如下内容:-debug options -vm javaw.exe 重新启动eclipse,就可以看到下方状态条多了JVM信息。b. 打开eclipse-窗口-首选项-Java-已安装的JRE(对在当前开发环境中运行的java程序皆生效)当前使用的JRE,在缺省VM参数中输入:-Xmx128m -Xms64m -Xmn32m -Xss16mc. 打开eclipse-运行-运行-Java应用程序(只对所设置的java类生效)选定需设置内存分配的类-自变量,在VM自变量中输入:-Xmx128m -Xms64m -Xmn32m -Xss16m注:如果在同一开发环境中同时进行了b和c设置,则b设置生效,c设置无效,如:开发环境的设置为:-Xmx256m,而类Test的设置为:-Xmx128m -Xms64m,则运行Test时生效的设置为:-Xmx256m -Xms64m(3)当在服务器环境下(如Tomcat)启动并使用JVM时(对当前服务器环境下所以Java程序生效):a. 设置环境变量:变量名:CATALINA_OPTS变量值:-Xmx128m -Xms64m -Xmn32m -Xss16mb. 打开Tomcat根目录下的bin文件夹,catalina.bat,将其中的�TALINA_OPTS%(共有四处)替换为:-Xmx128m -Xms64m -Xmn32m -Xss16m
更多文章:
autocad2013安装教程(win10系统autocad2013怎么安装)
2024年6月28日 05:53
安卓版iphoneqq(如何让安卓手机登QQ,让对方看到你是iPhone在线)
2024年5月28日 15:33
adobe cs6安装教程(adobe photoshop cs6怎么安装)
2024年5月28日 18:13
120帧画质助手下载安卓(画质助手120帧安卓和平精英怎么登录)
2024年3月29日 17:35
路由器怎样重新设置wifi密码(路由器怎样重新设置wifi密码)
2024年7月15日 09:18