由JVM内存空间想到的java编码规范

原创 2013年12月04日 15:18:37

    在方法(代码块)中定义一个变量时,java就在栈中为这个变量分配JVM内存空间,当超过变量的作用域后,java会自动释放掉为该变量所分配的JVM内存空间;而在堆中分配的JVM内存由java虚拟机的自动垃圾回收器来管理。

JVM内存区域组成

JVM内存分四种:

1、栈区(stacksegment)—由编译器自动分配释放,存放函数的参数值,局部变量的值等,具体方法执行结束之后,系统自动释放JVM内存资源

2、堆区(heapsegment)—一般由程序员分配释放,存放由new创建的对象和数组,jvm不定时查看这个对象,如果没有引用指向这个对象就回收

3、静态区(datasegment)—存放全局变量,静态变量和字符串常量,不释放

4、代码区(codesegment)—存放程序中方法的二进制代码,而且是多个对象共享一个代码空间区域

在方法(代码块)中定义一个变量时,java就在栈中为这个变量分配JVM内存空间,当超过变量的作用域后,java会自动释放掉为该变量所分配的JVM内存空间;在堆中分配的JVM内存由java虚拟机的自动垃圾回收器来管理,堆的优势是可以动态分配JVM内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配JVM内存的。缺点就是要在运行时动态分配JVM内存,存取速度较慢;栈的优势是存取速度比堆要快,缺点是存在栈中的数据大小与生存期必须是确定的无灵活性。

◆java堆由Perm区和Heap区组成,Heap区则由Old区和New区组成,而New区又分为Eden区,From区,To区,Heap={Old+NEW={Eden,From,To}},见图1所示。

Heap区分两大块,一块是NEWGeneration,另一块是OldGeneration.在NewGeneration中,有一个叫Eden的空间,主要是用来存放新生的对象,还有两个SurvivorSpaces(from,to),它们用来存放每次垃圾回收后存活下来的对象。在OldGeneration中,主要存放应用程序中生命周期长的JVM内存对象,还有个PermanentGeneration,主要用来放JVM自己的反射对象,比如类对象和方法对象等。

在NewGeneration块中,垃圾回收一般用Copying的算法,速度快。每次GC的时候,存活下来的对象首先由Eden拷贝到某个SurvivorSpace,当SurvivorSpace空间满了后,剩下的live对象就被直接拷贝到OldGeneration中去。因此,每次GC后,EdenJVM内存块会被清空。在OldGeneration块中,垃圾回收一般用mark-compact的算法,速度慢些,但减少JVM内存要求.

垃圾回收分多级,0级为全部(Full)的垃圾回收,会回收OLD段中的垃圾;1级或以上为部分垃圾回收,只会回收NEW中的垃圾,JVM内存溢出通常发生于OLD段或Perm段垃圾回收后,仍然无JVM内存空间容纳新的Java对象的情况。

JVM调用GC的频度还是很高的,主要两种情况下进行垃圾回收:当应用程序线程空闲;另一个是JVM内存堆不足时,会不断调用GC,若连续回收都解决不了JVM内存堆不足的问题时,就会报outofmemory错误。因为这个异常根据系统运行环境决定,所以无法预期它何时出现。

根据GC的机制,程序的运行会引起系统运行环境的变化,增加GC的触发机会。为了避免这些问题,程序的设计和编写就应避免垃圾对象的JVM内存占用和GC的开销。显示调用System.GC()只能建议JVM需要在JVM内存中对垃圾对象进行回收,但不是必须马上回收,一个是并不能解决JVM内存资源耗空的局面,另外也会增加GC的消耗。

◆当一个URL被访问时,JVM内存区域申请过程如下:

A.JVM会试图为相关Java对象在Eden中初始化一块JVM内存区域

B.当Eden空间足够时,JVM内存申请结束。否则到下一步

C.JVM试图释放在Eden中所有不活跃的对象(这属于1或更高级的垃圾回收),释放后若Eden空间仍然不足以放入新对象,则试图将部分Eden中活跃对象放入Survivor区

D.Survivor区被用来作为Eden及OLD的中间交换区域,当OLD区空间足够时,Survivor区的对象会被移到Old区,否则会被保留在Survivor区

E.当OLD区空间不够时,JVM会在OLD区进行完全的垃圾收集(0级)

F.完全垃圾收集后,若Survivor及OLD区仍然无法存放从Eden复制过来的部分对象,导致JVM无法在Eden区为新对象创建JVM内存区域,则出现"outofmemory错误"

由小游戏跳一跳想到的

元旦放假那天回家,一路上看到好多人都在玩那个游戏,感觉好巧啊,怎么都玩一个游戏。后来回到 家把微信更新了版本,赫然发发现了这个跳一跳的小游戏,玩了几次,最高玩到100多分,就没再玩了。 元旦回来上班...
  • zwl1584671413
  • zwl1584671413
  • 2018年01月04日 11:00
  • 122

由忧郁想到的

忧郁说的:有道德有文化有理想 为何没钱呢?而我认为:因为没有实力,没有学历没有资历,没有压力,没有动力,没有创造力,没有适应力,没有魄力,没有魅力,没有执行力,没有影响力!...
  • jasword
  • jasword
  • 2004年12月29日 04:07
  • 488

由玩游戏想到的

怎样才能快速上手一个游戏? 怎样才能快速掌握
  • ylfdrib
  • ylfdrib
  • 2014年04月13日 12:17
  • 449

由雪想到。。。。

大连今日降雪,飘飘洒洒,浑然天地。望着窗外,心有所想。。。想到了,川端康成的>;想到了,令狐冲在思过崖;想到了,香雪涧和晚来天欲雪,能饮一杯无?更想到了故乡的八景之"红崖积雪"......红崖积雪 红...
  • dragondwy
  • dragondwy
  • 2008年12月05日 12:06
  • 370

jvm的内存空间分块情况

在方法(代码块)中定义一个变量时,java就在栈中为这个变量分配JVM内存空间,当超过变量的作用域后,java会自动释放掉为该变量所分配的JVM内存空间;而在堆中分配的JVM内存由java虚拟机的自动...
  • u010363836
  • u010363836
  • 2016年04月07日 12:37
  • 1310

实例变量和类变量内存分配

Java向程序员许下一个承诺:无需关心内存回收,java提供了优秀的垃圾回收机制来回收已经分配的内存。大部分开发者肆无忌惮的挥霍着java程序的内存分配,从而造成java程序的运行效率低下! java...
  • u012036927
  • u012036927
  • 2013年11月03日 12:54
  • 1108

JVM的内部组成

JVM内部结构组成 JVM: Java虚拟机(Java VirtualMachine 简称JVM)是运行所有Java程序的抽象计算机,是Java语言的运行环境,它是Java 最具吸引力的特性之一。  ...
  • wuwenxiang91322
  • wuwenxiang91322
  • 2013年08月28日 15:15
  • 7007

从java线程到内存空间

1、实现线程的三种方式       使用内核线程实现     内核线程(KernelThread, KLT)就是直接由操作系统内核支持的线程,这种线程由内核来完成线程切换,内核通过操作调度器...
  • lantian0802
  • lantian0802
  • 2014年04月03日 13:41
  • 1218

Java基础学习总结---------异常Exception(3) -JVM默认如何处理异常

异常Exception 注:本人学习的是传智播客风清扬老师的java基础视频,刘老师讲的特别详细,本人只是把博客当作学习笔记。 public class ExceptionDemo { publ...
  • Jack_SivenChen
  • Jack_SivenChen
  • 2015年08月09日 20:39
  • 1317

JVM编译时和运行时,内存的分配

最近在看JVM内存分配的知识,现将自己的理解表述一下,要是有什么不对的地方,欢迎大家指正交流。 示例代码: public class Sample { int var1 = 1;...
  • aaa1117a8w5s6d
  • aaa1117a8w5s6d
  • 2012年12月10日 15:46
  • 1728
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:由JVM内存空间想到的java编码规范
举报原因:
原因补充:

(最多只允许输入30个字)