• 1. JAVA缓存体系及应用2010.10.27
  • 2. 目录带着问题来,带着答案走 JAVA内存体系介绍 基本缓存的使用 缓存框架的介绍 内存溢出状况分析 内存检查工具的使用
  • 3. 问题JVM内存的分配原理? JVM启动的时候如何正确的设置内存参数? JVM内存是不是越大越好? 什么情况下大家用到了缓存处理,很好的解决了问题? 缓存框架帮我们解决哪些问题,为什么要使用缓存框架? 你是如何进行内存溢出检查的?
  • 4. JAVA内存体系介绍操作系统的内存使用和管理 JVM内存的分类 JVM内存参数设置及作用 垃圾回收机制 内存实时状态查询
  • 5. 操作系统的内存使用和管理Windows内存使用 虚拟内存是Windows管理所有可用内存的方式。 Windows 32位为每个进程分配了4G的虚拟地址空间(用于表示该进程有这么多的空间可用),4G是由于操作系统+CPU是32位的,寻址空间就只有2的32次方,因此得出4G的存储空间。 Windows操作系统默认会给程序和系统预留2G的内存寻址空间;我们可以通过配置将应用程序的最大内存配置到3G。 4G配置 但电脑显示最多3.5内存 。因为:xp/vista 32bit在安装4G内存后会分配其中部分内存作为设备保留的内存地址。 64位就不存在4GB空间的束缚了。
  • 6. Application 2GB 用于程序存放代码,数据,堆栈,自由存储区 Windows System 2GB 共享内存,所有进程都用到的内存区域 操作系统规定:一个应用程序所能承载的最大寻址内存是2GB(可以通过配置改变到3GB),因为主要是为了预留一部分给操作系统使用,叫做共享内存区。 所以虽然一个程序理论上可以访问4GB内存,但是实际上只能分配2GB的空间。所以我们可以得出2个程序的最大使用内存是:2G(共享内存)+2*2G(程序内存)=6G
  • 7. 为什么我的电脑是2G内存,但是在系统可以使用超过2G的内存空间,大概有 4G!
  • 8. 页面文件以上情况是由于页面文件控制的。 这里很容易混淆一个概念,认为以上windows磁盘用来充当内存的叫做虚拟内存,其实windows管理的内存都叫做虚拟内存。所以虚拟内存是:RAM(物理内存)+页面文件(磁盘内存) 页面文件即当内存不够时系统会拿出一部分硬盘空间来充当内存使用,当内存占用完时,电脑就会自动调用硬盘来充当内存,以缓解内存的紧张。比如:你的机器有2G内存,当使用的内存超过2G时,超过的部分就会将硬盘上的文件映射成内存来使用。 按照这样逻辑我们不难得出只要虚拟内存够大,我们就可以无限制的使用,不过考虑到性能这也是不切实际的。 以上只是很浅显的一个理解,其实Windows虚拟内存的管理是一个比较复杂的处理过程,由于windows的多任务机制,再配合虚拟内存,其实windows运行的程序所占用的内存是远远超过可分配内存的。
  • 9. 应用程序1 内存 磁盘 1激活应用程序2分配相应的内存34回收内存5将内存内容映射到页面文件 并重新建立映射最小化应用程序67关闭应用程序释放虚拟内存应用程序2 89切换应用程序2读取页面文件放到物理内存中 并重新建立映射10操作系统来调度当物理内存吃紧的情况下,会产生大量的页入,页出动作,从而降低系统运行速度3-5:表示页入动作 8-10:表示页出动作
  • 10. 再来看看任务管理器总数:RAM物理内存总大小 可用数:当前RAM内存还剩余多少 系统缓存:指的是系统共享内存使用量提交更改(前面的): 实际是虚拟内存使用量,包括RAM和页面文件 提交更改(后面的): 虚拟内存的总量总RAM+总的页面文件
  • 11. 进程内存使用量,该数据指的是程序独占RAM内存和使用到的系统共享内存因为有共享成分在里面,所以所有程序内存加起来不一定等于系统RAM使用的总量。虚拟内存大小,指的是程序所用到的所有2G虚拟内存的寻址空间大小,一般会包含在RAM、页面文件、exe和dll中。
  • 12. 关于Linux的内存管理Windows管理内存更加规范和统一,通过统一的内存映射和跟踪机制来完成,但是同时也失去了一定的灵活性。 Linux管理内存不是很规范,省去了内存映射,而是直接将内存提交到页面,并且只有当页面被真正使用了,才会将其绑定到内存中中。
  • 13. JVM内存分类系统级内存分配 JVM的内存分配机制其实也是基于操作系统分配机制 JVM最大的内存在win32下是2G JVM的内存使用情况实际被分为:JVM虚拟机、JAVA程序的字节码(classes)、系统内存空间Native Heap(主要用于存放线程和一些系统级的对象和操作)、JAVA内存Java Heap(真正的存放Java Object 的内存区域)
  • 14. Application 2GB 用于程序存放代码,数据,堆栈,自由存储区 Windows System 2GB 共享内存,所有进程都用到的内存区域 JvmPermanetNative HeapJava HeapSystem libJAVA程序本身使用的内存区域存放线程、系统变量、一些类似Runtime的操作存放具体的Classes、Jar信息注意:所以我们在给Java程序分配内存时是分不到2G空间的JNI的调用
  • 15. JVM内存分配管理JVM如何管理内存 永久存储区(Permanent Space):永久存储区是JVM的驻留内存,用于存放JDK自身所携带的Class,Interface的元数据。 堆空间(The Heap Space):JAVA对象的出生,成长,死亡都在这个区域完成;堆空间又分为养老区和新生区。 新生区(Young (New) generation space):新生区的作用包括JAVA对象的创建和从JAVA对象中筛选出能进入养老区的JAVA对象。 伊甸园(Eden space):JAVA对空间中的所有对象在此出生,该区的名字因此而得名。也即是说当你的JAVA程序运行时,需要创建新的对象,JVM将在该区为你创建一个指定的对象供程序使用。创建对象的依据即是永久存储区中的元数据。 幸存者0区(Survivor 0 space)和幸存者1区(Survivor1 space):当伊甸园的控件用完时,程序又需要创建对象;此时JVM的垃圾回收器将对伊甸园区进行垃圾回收,将伊甸园区中的不再被其他对象所引用的对象进行销毁工作。同时将伊甸园中的还有其他对象引用的对象移动到幸存者0区。如果0区域也没有空间了就会向1区移动。 养老区(Tenure (Old) generation space):用于保存从新生区筛选出来的JAVA对象。
  • 16. JAVA所有管理的内存永久内存区域(Permanent): 存放Classes、Jar等数据养老区(Tenured) (其实可以看作是”终极”幸存者)伊甸园区(eden)幸存者区0(survivor0) From幸存者区1(survivor1) To堆空间(Java Heap Space)
  • 17. JVM内存参数设置Permagnet (永久区)Extend Virtual (永久区虚拟内存)Tenured (养老区)Extend Virtual (养老区虚拟内存)Enden (伊甸园)Survivor0 (幸存者0)Survivor0 (幸存者1)Extend Virtual (幸存者区虚拟内存)-XX:MaxPermSize-XX:PermSize-Xmx(最大内存配置)-Xms(最小内存配置,初始养老区+年轻区)-XX:MaxNewSize(最大年轻区大小)-XX:NewSize(年轻区大小)-XX:SurvivorRatio (设置年轻代中Eden区与Survivor区的大小比值)-XX:NewRatio (设置年轻代(包括Eden和两个Survivor区)与年老代的比值)Permagnent 空间Java Heap Space空间
  • 18. 垃圾回收机制首先当启动J2EE应用服务器时,JVM随之启动,并将JDK的类和接口,应用服务器运行时需要的类和接口以及J2EE应用的类和接口定义文件也及 编译后的Class文件或JAR包中的Class文件装载到JVM的永久存储区。在伊甸园中创建JVM,应用服务器运行时必须的JAVA对象,创建 J2EE应用启动时必须创建的JAVA对象;J2EE应用启动完毕,可对外提供服务。 JVM在伊甸园区根据用户的每次请求创建相应的JAVA对象,当伊甸园的空间不足以用来创建新JAVA对象的时候,JVM的垃圾回收器执行对伊甸园区的垃 圾回收工作,销毁那些不再被其他对象引用的JAVA对象(如果该对象仅仅被一个没有其他对象引用的对象引用的话,此对象也被归为没有存在的必要,依此类 推),并将那些被其他对象所引用的JAVA对象移动到幸存者0区。 如果幸存者0区有足够控件存放则直接放到幸存者0区;如果幸存者0区没有足够空间存放,则JVM的垃圾回收器执行对幸存者0区的垃圾回收工作,销毁那些不 再被其他对象引用的JAVA对象(如果该对象仅仅被一个没有其他对象引用的对象引用的话,此对象也被归为没有存在的必要,依此类推),并将那些被其他对象 所引用的JAVA对象移动到幸存者1区。 如果幸存者1区有足够控件存放则直接放到幸存者1区;如果幸存者0区没有足够空间存放,则JVM的垃圾回收器执行对幸存者0区的垃圾回收工作,销毁那些不 再被其他对象引用的JAVA对象(如果该对象仅仅被一个没有其他对象引用的对象引用的话,此对象也被归为没有存在的必要,依此类推),并将那些被其他对象 所引用的JAVA对象移动到养老区。 如果养老区有足够控件存放则直接放到养老区;如果养老区没有足够空间存放,则JVM的垃圾回收器执行对养老区区的垃圾回收工作,销毁那些不再被其他对象引 用的JAVA对象(如果该对象仅仅被一个没有其他对象引用的对象引用的话,此对象也被归为没有存在的必要,依此类推),并保留那些被其他对象所引用的 JAVA对象。如果到最后养老区,幸存者1区,幸存者0区和伊甸园区都没有空间的话,则JVM会报告“JVM堆空间溢出 (java.lang.OutOfMemoryError: Java heap space)”,也即是在堆空间没有空间来创建对象。 这就是JVM的内存分区管理,相比不分区来说;一般情况下,垃圾回收的速度要快很多;因为在没有必要的时候不用扫描整片内存而节省了大量时间。 通常大家还会遇到另外一种内存溢出错误“永久存储区溢出(java.lang.OutOfMemoryError: Java Permanent Space)”。
  • 19. System.gc();其实并不一定立即触发垃圾回收。只是告诉系统现在该进行垃圾回收了。 JVM的垃圾回收一种自动的处理机制。 垃圾回收太频繁会对系统造成一定的压力,因为要遍历所有的内存区域。
  • 20. 基本缓存的使用为什么使用缓存 JAVA集合类的应用(HashMap) JAVA单例
  • 21. 为什么使用缓存大量的数据库IO操作;例如:循环获取一个用户信息,从缓存中读取则能提交几十倍至上百倍的性能。 Socket通信的异步缓冲池,避免线程的阻塞,将通信的信息放置到缓存中。 一些通用页面、JS、CSS的加载,减少对本地文件的操作。 异步信息存储,例如:UCALL的中的消息存储。 统计和计算时暂存的一些信息,加快统计的效率。
  • 22. JAVA集合类HashMap基本上所有的缓存都是基于HashMap结构存储的;HashMap是一种高效的数据存储方式。 HashMap的get和put方法 HashMap与ArrayList的比较
  • 23. JAVA单例要使得缓存生效,一般而言都需要将持有缓存对象的对象设置成单例的,变成不可销毁的对象,让垃圾回收器在处理的时候不会自动将其销毁掉,这样下次能继续进行使用。 由于不同的Cache我们需要不同的实体去处理,因为不可能所有的对象都存储在一个Cache里面,这样就没法索引和获取当前Cache的数量了,因此需要进行区分和管理;所以就需要框架的支持。
  • 24. 缓存框架的介绍Oscache缓存架构 Ehcache缓存架构 Memcached缓存架构 JiveCache缓存架构 Terracotta JVM级缓存架构
  • 25. OSCache缓存架构快速缓存机制,控制缓存的时间和大小 支持页面式的缓存方式 支持本地文件、JDBC、JNI缓存方式 支持集群缓存的部署(性能比较差) 截至到2007没发现有任何更新
  • 26. AbstractCacheAdministrator该类主要是进行缓存的初始化:缓存算法、大小、集群等的配置。GeneralCacheAdministrator所有缓存对象的抽象基类,如果需要使用缓存,则必须扩展该类。该类出要处理缓存的添加、获取、删除等基本动作。AbstractAbstractCacheAbstractConcurrentReadCacheFIFOCache (最先进来的最先清理掉)LRUCache (最少使用的最先清理掉)UnlimitedCache (缓存大小=-1的情况下不用计数也不用清理)缓存MAPSize不为0的情况下OSCacheUcstarCacheManagerBaseCacheCache1Cache2……
  • 27. Oscache集群JMS、RMI、JgroupsOscache01Application01CacheJavaCacheListnenerOscache02Application02CacheJavaCacheListnenerOscache03Application03CacheJavaCacheListnener基于RMI、Jgroups、JMS的集群通信协议 需自己编写本地的集群扩展实现类并更新本地缓存
  • 28. 优缺点优点:使用简单,开发容易。 缺点:性能太差,集群部署麻烦。
  • 29. Ehcache从Hibernate项目发展起来,目前被Terracotta收购开发统一的缓存的解决方案 持续的维护和发布中 标准的缓存支持(最大数配置、移除算法、磁盘持久化、重启缓存持久化) 分布式缓存(RMI、Jgroups、JMS) 集中式缓存(类似Memcached) 页面缓存技术(Oscache)
  • 30. CacheManager(缓存管理中心)ehcache.xmlEhcache的管理类,所有的缓存的控制都是通过该管理类来进行处理的。CacheStoreMemory StoreDisk Store包含LRU、FIFO、LFU三种CacheLoaderCacheListenerRMI ReplicationJMS ReplicationJgroups Replication核心模块分布式扩展模块UcstarCacheManagerIEhCacheCache1Cache2UcstarEhcache
  • 31. 集群部署方式-分散部署JMS、RMI、JgroupsEhcache01Application01CacheJavaCacheListnenerEhcache02Application02CacheJavaCacheListnenerEhcache03Application03CacheJavaCacheListnener与Oscache比较相似,只是Ehcache不用自己进行这些维护,可全部交由Ehcache程序来处理可手动配置RMI地址或者采用Jgroups自动分配
  • 32. Server集群集群部署方式-集中部署LoadBalaceEhcache Server01这种方式比较类似MemCache,但是因为是Http请求,所以效率不高。Application (JAVA、PHP、ASP)Ehcache Server02Ehcache Server03Http请求
  • 33. 优缺点优点:结构清晰,使用简单,效率高,扩展性比较好。 缺点:集中式缓存部署比较鸡肋,页面缓存过于麻烦。
  • 34. MemCached缓存体系MemCached是一种集中式缓存部署 采用C代码编写 客户端的访问有多种不同的代码实现方式 支持大规模集群的部署方式 支持横向的分布式扩展方式 支持Slave、Master模式 FaceBook、阿里巴巴都是采用这种部署方式
  • 35. 最简单的应用MemcachedApplication1 (JAVA、PHP、ASP)Socket请求Application2 (JAVA、PHP、ASP)Socket请求Load Balance
  • 36. 分布式应用Memcached1Application1 (JAVA、PHP、ASP)Socket请求Application2 (JAVA、PHP、ASP)Load BalanceMemcached2Memcached3将实例分布在不同的Memcached中
  • 37. 分布式+集群Memcached1Application1 (JAVA、PHP、ASP)Application2 (JAVA、PHP、ASP)Load BalanceMemcached2Memcached3通过扩展集群解决部分数据单点丢失问题。Memcached4Client MemcacheCluster1Client MemcacheCluster2数据同步本地程序调用CacheManager
  • 38. 优缺点优点:集中式管理,不用考虑数据的复制,部署简单;支持分布式扩展,减少数据全部丢失的问题,减少数据的存储;客户端调用无关。 缺点:性能不如节点均衡网状结构,需考虑单点故障问题,缓存遍历很麻烦因为不支持不同类型的缓存存储方式,对于复杂的缓存结构支持的较差。 一般应用在网站、电子商务等系统上
  • 39. JiveCache缓存架构类似Oscache的实现机制 只有基本的本地缓存实现方式 通过适配器模式扩展出了Ehcache、Memcached、Oscache的解决方案
  • 40. CacheManagerCacheCache1Cache2UcstarMemCachedUcstarOsCacheUcstarEhCacheUcstarCacheManager适配了其他的实现方式
  • 41. Terracotta JVM级缓存架构Terracotta核心平台是一个基于 JVM的集群解决方案,允许用户在不修改代码的情况下把单机 Java应用程序运行在多 JVM的集群中。 其主要功能特点如下: 实现单机Java应用到集群环境的平滑移植 允许Java程序像访问本地数据数据一样访问集群共享数据,并且实现对共享数据的集群范围内的访问同步 提供给予网络的虚拟内存管理,允许Java程序访问超过其内存空间(heap)的数据 数据保存在服务器端,因此客户端JVM宕机不会造成数据丢失 增量数据传递,智能数据推送,最大限度减少对网络的负担,使得客户端JVM可以横向扩展 主从服务器配置,支持多台从服务器,实现高可用服务器 服务器分片,实现服务器数据存储及数据吞吐量横向扩展 通过JMX开放服务器监控信息 提供可视化监控和管理界面,大大方便对整合集群的共享数据、性能数据、软硬件指标等的实施监控、调试、优化 Terracotta DSO核心平台提供了一个稳健、高效、高可用、易用、易管理的 Java集群平台。 Terracotta为了进一步帮助 J2EE开发人员充分利用其核心平台提供的各项特性,针对 Java开发人员常用的 Java技术平台提供了一系列快捷模式( Express Mode)的解决方案,包括 Ehcache分布式缓存、 Hibernate分布式二级缓存、 Web Session集群、 分布式 Java任务调度 Quartz等等。 使用快捷模式,可以避免客户端程序对 JDK和应用服务器的依赖、避免配置 tc-config.xml文件等等。用户直接拷贝相应的 jar文件,对方案相关的配置文件进行简单修改(比如 ehcache.xml, hibernate.cfg.xml文件等等),就可以实现集群化了。 后面将逐一介绍 Terracotta快捷模式支持的解决方案。
  • 42. 内存溢出状况分析Java heap space溢出:JAVA本身的内存不足,通过修改-Xms和-Xmx来解决。 Java PermGen space溢出:JAVA的Permgenant区域的内存不足,修改-XX:PermSize和-XX:MaxPermSize来解决。 Java Native space溢出:JAVA线程内存不够、JNI调用内存不够;是属于JAVA本身以外的内存泄漏。
  • 43. 内存检查工具的使用Jconsole:JDK1.5以后增加的检查工具 Jrockit:前身是BEA公司开发的JVM,后被IBM收购,是目前最好的内存检查工具。
  • 44. JconsoleJConsole是一个基于JMX的GUI工具,用于连接正在运行的JVM,不过此JVM需要使用可管理的模式启动。如果要把一个应用以可管理的形式启 动,可以在启动是设置com.sun.management.jmxremote。例如,启动一个可以在本地监控的J2SE的应用Java2Demo ,需输入以下命令:   JDK_HOME/bin/java -Dcom.sun.management.jmxremote -jar [b]JDK_HOME/demo/jfc/Java2D/Java2Demo.jar
  • 45. (本页无文本内容)
  • 46. JRockit在需要被jrockit调用的应用中添加以下参数: %JAVA_HOME%\bin\java %JAVA_VM% -Xms32m -Xmx256m -Xmanagement:port=7091,ssl=false,authenticate=false
  • 47. (本页无文本内容)
  • 48. 谢谢