因为每个对象生命周期不一样,jvm在做内存管理的时候,就帮我们分成了三个区域:

  1.  新生代(回收频率高)   新生和老年默认大小比例为1:2

  2.  老年代(回收频率低)     最好所有的对象都不要进入老年代,最好新生代能及时回收空对象释放空间供下次使用。

  3.  永久代(一般放类的加载信息,常量,静态变量)。

  从上图可以看出jdk1.8之前:新生代,老年代放在heap中, 永久代放在方法区中;

  在jdk1.8的时候,就将永久代放到了一块叫Meta Space(元空间)的本地内存中。

   官方之所以这么设计,是为了解决永久代会溢出的问题,meta space有点像ArrayList,拥有自动扩容的特性,从而防止溢出。当然它也不是越大越好,太大了会因为内存占用过多,从而使得堆外内存空间狭小而容易出现内存溢出的情况。这些都是可配置的。

指针碰撞:

  如下图,第一次创建对象的时候线程开辟了一个空间,第二次创建对象线程又开了一个空间,如果多个线程同时创建就会出现“抢占”空间的情况出现指针碰撞,jvm就通过CAS来控制先来后到的顺利,理解成线程锁一样。但是这样创建对象还是CAS还是会出现竞争激烈的情况从而消耗CPU影响性能。为了解决这个问题,jvm又提供了栈上分配。内存规整(即内存连续有规律)

    

栈上分配:

  栈上分配的本质还是在堆中分配内存。

  如下图:在堆里面,每个线程都有自己的Thread local Alltion Buffer,他们都是在自己的空间里面创建对象,这样就不会出现抢占的情况了,从而提高了性能。

对象分配规则:

  (1)对象优先分配在Eden区,如果Eden内存不够,虚拟机就执行一次Minor GC

  (2)大对象(大对象指需要大量连续内存空间的对象)直接进入老年代.这样做的目的是避免在Eden区和两个Survivor区之间发生大量的内存拷贝(新生代采用复制算法收集内存)。

  (3)长期存活的对象进入老年代.虚拟机为每个对象都定义一个年龄计数器,如果对象经过一次Minor GC就去Survivor区,之后每经过一次Minor GC,年龄就会加一,直到15之后就去老年代.

  (4)动态判断对象的年龄.如果Survivor区相同年龄的对象的总和大于Survivor的一半,那么大于或者等于这个年龄的对象直接去老年代

最新文章

  1. 利用Unity制作“表”
  2. Python 2.7_First_try_爬取阳光电影网_20161206
  3. Responsive布局技巧
  4. POJ 3041 Asteroids(最小点覆盖集)
  5. [转载]async & await 的前世今生
  6. mac jdbc连接mysql
  7. 用上Google才是正事 分享几个訪问Google的IP和域名
  8. Java多线程之Lock的使用(转)
  9. 在Eclipse中创建Django项目
  10. sqlserver 按照特定值排序查询结果
  11. 【转】Spring-boot 字符集设置 解决乱码方案
  12. Linux系统下用find命令查找最近修改过的文件
  13. c#之枚举,结构体
  14. MySQL主从.md
  15. Linux netstat 命令
  16. vue版本,小Toast
  17. QT延时方法
  18. 倍福TwinCAT(贝福Beckhoff)应用教程13.3 TwinCAT控制松下伺服 NC配合完整上位
  19. <2013 12 01> 一篇很好的关于windows编程的入门指导(2013年末写的,比较前沿)
  20. vue-cli构建的项目打包出现里面的js,css缺少dist路径

热门文章

  1. html button标签 语法
  2. Codeforces 960F Pathwalks ( LIS && 树状数组 )
  3. [BZOJ3796]Mushroom追妹纸:后缀自动机+KMP
  4. Spring Boot教程(十四)快速入门
  5. Oracle数据库表空间创建、添加用户并授权
  6. Hbase meta 表异常修复
  7. long poll、ajax轮询和WebSocket
  8. 高级软件测试技术-小组任务分配和安排-Day01
  9. ZXing使用详解与范例(C#)
  10. MVC Areas的使用