java栈内存堆内存和GC相关

java栈内存堆内存

Java把内存分成两种,一种叫做栈内存,一种叫做堆内存,有着不同的作用。栈内存用来存储局部变量和方法调用。
栈内存归属于单个线程,每个线程都会有一个栈内存,其存储的变量只能在其所属线程中可见,即栈内存可以理解成线程的私有内存。
而堆内存中的对象对所有线程可见。堆内存中的对象可以被所有线程访问。而堆内存用来存储Java中的对象。无论是成员变量,局部变量,还是类变量,它们指向的对象都存储在堆内存中。

引用变量是普通变量,定义时在栈中分配内存,引用变量在程序运行到作用域外释放。而数组&对象本身在堆中分配,即使程序运行到使用new产生数组和对象的语句所在地代码块之外,数组和对象本身占用的堆内存也不会被释放,组和对象在没有引用变量指向它的时候,才变成垃圾,不能再被使用,但是仍然占着内存,在随后的一个不确定的时间被垃圾回收器释放掉。这个也是java比较占内存的主要原因,实际上,栈中的变量指向堆内存中的变量,这就是 Java 中的指针!

javaGC和调优

Java的垃圾回收机制是通过GC线程执行的,它是java虚拟机自己使用的守护线程。负责清理所谓的"不可达"的对象。当程序创建对象时,GC就开始监控这个对象的地址、大小以及使用情况。当GC确定一些对象为"不可达"时,GC就有责任回收这些内存空间.

以下列出jvm常用参数供调优时参考

参数名称 含义 默认值  
-Xms 初始堆大小 物理内存的1/64(<1GB) 默认(MinHeapFreeRatio参数可以调整)空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制.
-Xmx 最大堆大小 物理内存的1/4(<1GB) 默认(MaxHeapFreeRatio参数可以调整)空余堆内存大于70%时,JVM会减少堆直到 -Xms的最小限制
-Xmn 年轻代大小(1.4or lator)   注意:此处的大小是(eden+ 2 survivor space).与jmap -heap中显示的New gen是不同的。
整个堆大小=年轻代大小 + 年老代大小 + 持久代大小.
增大年轻代后,将会减小年老代大小.此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8
-XX:NewSize 设置年轻代大小(for 1.3/1.4)    
-XX:MaxNewSize 年轻代最大值(for 1.3/1.4)    
-XX:PermSize 设置持久代(perm gen)初始值 物理内存的1/64  
-XX:MaxPermSize 设置持久代最大值 物理内存的1/4  
-Xss 每个线程的堆栈大小   JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K.更具应用的线程所需内存大小进行 调整.在相同物理内存下,减小这个值能生成更多的线程.但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右
一般小的应用, 如果栈不是很深, 应该是128k够用的 大的应用建议使用256k。这个选项对性能影响比较大,需要严格的测试。(校长)
和threadstacksize选项解释很类似,官方文档似乎没有解释,在论坛中有这样一句话:"”
-Xss is translated in a VM flag named ThreadStackSize”
一般设置这个值就可以了。
-XX:ThreadStackSize Thread Stack Size   (0 means use default stack size) [Sparc: 512; Solaris x86: 320 (was 256 prior in 5.0 and earlier); Sparc 64 bit: 1024; Linux amd64: 1024 (was 0 in 5.0 and earlier); all others 0.]
-XX:NewRatio 年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代)   -XX:NewRatio=4表示年轻代与年老代所占比值为1:4,年轻代占整个堆栈的1/5
Xms=Xmx并且设置了Xmn的情况下,该参数不需要进行设置。
-XX:SurvivorRatio Eden区与Survivor区的大小比值   设置为8,则两个Survivor区与一个Eden区的比值为2:8,一个Survivor区占整个年轻代的1/10
-XX:LargePageSizeInBytes 内存页的大小不可设置过大, 会影响Perm的大小   =128m
-XX:+UseFastAccessorMethods 原始类型的快速优化    
-XX:+DisableExplicitGC 关闭System.gc()   这个参数需要严格的测试
-XX:MaxTenuringThreshold 垃圾最大年龄   如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代. 对于年老代比较多的应用,可以提高效率.如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象再年轻代的存活 时间,增加在年轻代即被回收的概率
该参数只有在串行GC时才有效.
-XX:+AggressiveOpts 加快编译    
-XX:+UseBiasedLocking 锁机制的性能改善    
-Xnoclassgc 禁用垃圾回收    
-XX:SoftRefLRUPolicyMSPerMB 每兆堆空闲空间中SoftReference的存活时间 1s softly reachable objects will remain alive for some amount of time after the last time they were referenced. The default value is one second of lifetime per free megabyte in the heap
-XX:PretenureSizeThreshold 对象超过多大是直接在旧生代分配 0 单位字节 新生代采用Parallel Scavenge GC时无效
另一种直接在旧生代分配的情况是大的数组对象,且数组中无外部引用对象.
-XX:TLABWasteTargetPercent TLAB占eden区的百分比 1%  
-XX:+CollectGen0First FullGC时是否先YGC false  

并行收集器相关参数

-XX:+UseParallelGC Full GC采用parallel MSC
(此项待验证)
 
选择垃圾收集器为并行收集器.此配置仅对年轻代有效.即上述配置下,年轻代使用并发收集,而年老代仍旧使用串行收集.(此项待验证)

-XX:+UseParNewGC 设置年轻代为并行收集   可与CMS收集同时使用
JDK5.0以上,JVM会根据系统配置自行设置,所以无需再设置此值
-XX:ParallelGCThreads 并行收集器的线程数   此值最好配置与处理器数目相等 同样适用于CMS
-XX:+UseParallelOldGC 年老代垃圾收集方式为并行收集(Parallel Compacting)   这个是JAVA 6出现的参数选项
-XX:MaxGCPauseMillis 每次年轻代垃圾回收的最长时间(最大暂停时间)   如果无法满足此时间,JVM会自动调整年轻代大小,以满足此值.
-XX:+UseAdaptiveSizePolicy 自动选择年轻代区大小和相应的Survivor区比例   设置此选项后,并行收集器会自动选择年轻代区大小和相应的Survivor区比例,以达到目标系统规定的最低相应时间或者收集频率等,此值建议使用并行收集器时,一直打开.
-XX:GCTimeRatio 设置垃圾回收时间占程序运行时间的百分比   公式为1/(1+n)
-XX:+ScavengeBeforeFullGC Full GC前调用YGC true Do young generation GC prior to a full GC. (Introduced in 1.4.1.)
时间: 2024-07-30 18:33:13

java栈内存堆内存和GC相关的相关文章

【Java基础】堆内存详解

Java 中的堆是 JVM 所管理的最大的一块内存空间,主要用于存放各种类的实例对象. 在 Java 中,堆被划分成两个不同的区域:新生代 ( Young ).老年代 ( Old ).新生代 ( Young ) 又被划分为三个区域:Eden.From Survivor.To Survivor. 这样划分的目的是为了使 JVM 能够更好的管理堆内存中的对象,包括内存的分配以及回收. 堆的内存模型大致为:  新生代:Young Generation,主要用来存放新生的对象. 老年代:Old Gene

Java栈与堆

Java栈与堆 ----对这两个概念的不明好久,终于找到一篇好文,拿来共享 1. 栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方.与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆. 2. 栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器.但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性.另外,栈数据可以共享,详见第3点.堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,Java的垃圾收集器会自动收走这些不再使用的数据.

java中的堆内存和栈内存

Java把内存分成两种: 一种叫做栈内存 一种叫做堆内存 栈内存 : 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配.当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量分配的内存空间,该内存空间可以立刻被另作他用. 堆内存 : 堆内存用于存放由new创建的对象和数组.在堆中分配的内存,由java虚拟机自动垃圾回收器来管理.在数组和对象在没有引用变量指向它的时候,才变成垃圾,不能再被使用,但是仍然占着

Java中的堆内存与栈内存

1.栈内存用来存放一些基本类型的变量.数组和对象的引用:堆内存主要用来存放一些对象. 2.static变量:静态变量是static修饰的变量,实例变量是非static修饰的变量. 3.静态变量与实例变量的区别: 1)静态变量是随着类加载时被完成初始化,它可以在内存中仅有一个,且JVM也只会为它分配一次内存,同时所有类的实例都共享静态变量,可以通过类名来直接访问. 2)实例变量是随着实例的,每创建一个实例就会产生一个实例变量,它与该实例同生共死. 4.static方法: static修饰的方法称之

实例化,掌握栈与堆内存的关系

JAVA中到底有多少内存区域呢? 1)栈内存:可以保存对象的名称(保存,访问的堆内存地址). 2)堆内存:保存每个对象的全局属性. 3)全局数据区:保存static类型的属性. 4)全局代码区:保存所有方法的定义. 1.声明对象,Person per,栈内存中声明,与数组一样,数组名称保存在栈内存中,只开辟栈内存的对象是无法使用的,必须有其堆内存的引用才能使用. 2,实例化对象,new Person();在堆中开辟内存空间,所有内容都是默认的. 3,String:是一个字符串,首字符是大写的,本

实例化,掌握栈与堆内存的关系(转)

JAVA中到底有多少内存区域呢? 1)栈内存:可以保存对象的名称(保存,访问的堆内存地址). 2)堆内存:保存每个对象的全局属性. 3)全局数据区:保存static类型的属性. 4)全局代码区:保存所有方法的定义. 1.声明对象,Person per,栈内存中声明,与数组一样,数组名称保存在栈内存中,只开辟栈内存的对象是无法使用的,必须有其堆内存的引用才能使用. 2,实例化对象,new Person();在堆中开辟内存空间,所有内容都是默认的. 3,String:是一个字符串,首字符是大写的,本

JavaScript栈和堆内存,作用域

1.栈 stack"和"堆 heap": 简单的来讲,stack上分配的内存系统自动释放,heap上分配的内存,系统不释放,哪怕程序退出,那一块内存还是在那里.stack一般是静态分配内存,heap上一般是动态分配内存. 2.基本类型和引用类型: 基本类型:存放在栈内存中的简单数据段.数据大小确定,内存空间大小可以分配. 引用类型:存放在堆内存中的对象,变量中实际保存的是一个指针,这个指针指向另一个位置.每个空间大小不一样,要根据情况开进行特定的分配. 详见<Javas

通俗的比较,堆主要用来存放对象的,栈主要是用来执行程序的. 堆内存与栈内存 ,,堆内存与栈内存能不能共享

创建一个对象都在内存中做了什么事情? 1:先将硬盘上指定位置的Person.class文件加载进内存.2:执行main方法时,在栈内存中开辟了main方法的空间(压栈-进栈),然后在main方法的栈区分配了一个变量p.3:在堆内存中开辟一个实体空间,分配了一个内存首地址值.new4:在该实体空间中进行属性的空间分配,并进行了默认初始化.5:对空间中的属性进行显示初始化.6:进行实体的构造代码块初始化.7:调用该实体对应的构造函数,进行构造函数初始化.()8:将首地址赋值给p ,p变量就引用了该实

栈内存 堆内存

栈内存:顺序结构   基本数据类型在栈内存中分配     例如:int x = 100    x不是对象 堆内存:离散结构   引用数据类型在堆内存中分配     例如: person  p1 = new person();  p1就是个对象   对象就是堆内存分配  怎么区分呢  p1.  对象加点就能出现属性    x.   不能出现属性   这样就能区分是不是对象 对象一定是创建在堆内存中