eden

JVM垃圾回收算法图解

女生的网名这么多〃 提交于 2019-11-28 19:47:04
参考文档:https://www.toutiao.com/a6691966641242112516/ 垃圾搜集算法 标记-清除法 标记-清除算法采用从根集合(GC Roots)进行扫描,对存活的对象进行标记,标记完毕后,再扫描整个空间中未被标记的对象,进行回收,如下图所示。 标记-清除算法不需要进行对象的移动,只需对不存活的对象进行处理,在存活对象比较多的情况下极为高效。但由于标记-清除算法直接回收不存活的对象,因此会造成内存碎片。 复制算法 复制算法的提出是为了克服句柄的开销和解决内存碎片的问题。 它开始时把堆分成 一个对象面和多个空闲面, 程序从对象面为对象分配空间,当对象满了,基于copying算法的垃圾收集就从根集合(GC Roots)中扫描活动对象,并将每个活动对象复制到空闲面(使得活动对象所占的内存之间没有空闲洞)。这样空闲面变成了对象面,原来的对象面变成了空闲面,程序会在新的对象面中分配内存。 标记-整理算法 标记-整理算法采用标记-清除算法一样的方式进行对象的标记,但在清除时不同,在回收不存活的对象占用的空间后,会将所有的存活对象往左端空闲空间移动,并更新对应的指针。 标记-整理算法是在标记-清除算法的基础上,又进行了对象的移动,因此成本更高,但是却解决了内存碎片的问题。 具体流程见下图: 分代收集算法 分代收集算法是目前大部分JVM的垃圾收集器采用的算法

jvm对象内存分配

╄→гoц情女王★ 提交于 2019-11-27 23:26:04
一、jvm简单结构图        1、jvm内存对象分配整体流程:        1、类加载子系统和方法区     类加载子系统负责从文件系统或者网络中加载Class信息,加载的类信息存放于一块称为方法区的内存空间。除了类的信息外,     方法区中可能还会存放运行时常量池信息,包括字符串字面量和数字常量(这部分常量信息是Class文件中常量池部分的内存映射)。   2、java堆     堆空间在jvm启动的时候即根据设置(后续 jvm参数调优)创建,是java程序中最主要的内存工作区域。堆空间是所有线程共享的。     jvm分配对象,一般来说,new个新对象,都是分配在堆空间的。其实这也不是绝对的,存在部分对象的分配是在栈上以及TLAB中。     TLAB:全称 Thread Local Allocation Buffer,线程本地分配缓存区,是一个为线程分配的专用的内存使用区域。在使用参数 -XX:UseTLAB 打开设置的时候,在进行         线程初始化的时候,会去分配一小块的内存区域供线程使用,这样如果使用,直接在自己的内存区域就可以直接分配使用了,提高效率。         默认的空间大小为Eden区的 1%,-XX:TLABWasteTargetPercent可以设置 TLAB 占 Eden区的百分比大小。     对象分配流程图:        上图:

【题解】lugu P4095 Eden的新背包问题

試著忘記壹切 提交于 2019-11-27 19:41:48
总结: 1. 50分的代码(因为由多个数据,所以不能改变num[]数组) #include<bits/stdc++.h> using namespace std; struct node{ int pos, value; }que[1005]; int c[1005], w[1005], num[1005], f[1005], vis[1005]; int n, head, tail, V, q, h, z[1005]; int main() { cin >> n; for(int i = 0; i < n; i++) cin >> c[i] >> w[i] >> num[i]; cin >> q; for(int cnt = 1; cnt <= q; cnt++) { memset(f, 0, sizeof(f)); cin >> h >> V; vis[h] = 1; for(int i=0;i<n;i++) { if(!vis[i]) { z[i] = min(num[i], V/c[i]); //用z[]数组代表能用多少件物品 for(int mo=0;mo<c[i];mo++) { head=tail=0; for(int k=0;k<=(V-mo)/c[i];k++) { int x=k; int y=f[k*c[i]+mo]-k*w[i]; while(head

Java内存管理

霸气de小男生 提交于 2019-11-27 19:23:08
Java内存管理 Java运行时内存区 其中,对于这各个部分有一些是线程私有的,其他则是线程共享的。 线程私有的如下: 程序计数器当前线程所执行的字节码的行号指示器 Java虚拟机栈Java方法执行的内存模型,每个方法被执行时都会创建一个栈帧,存储局部变量表、操作栈、动态链接、方法出口等信息。 每个线程都有自己独立的栈空间 线程栈只存基本类型和对象地址 方法中局部变量在线程空间中 本地方法栈Native方法服务。在HotSpot虚拟机中和Java虚拟机栈合二为一。 线程共享的如下: Java堆存放对象实例,几乎所有的对象实例以及其属性都在这里分配内存。 方法区存储已经被虚拟机加载的类信息、常量、静态变量、JIT编译后的代码等数据。 运行时常量池方法区的一部分。用于存放编译期生成的各种字面量和符号引用。 直接内存NIO、Native函数直接分配的堆外内存。DirectBuffer引用也会使用此部分内存。 对象访问 Java是面向对象的一种编程语言,那么如何通过引用来访问对象呢?一般有两种方式: 1.通过句柄访问 2.直接指针(此种方式也是HotSpot虚拟机采用的方式) 内存溢出 在JVM申请内存的过程中,会遇到无法申请到足够内存,从而导致内存溢出的情况。一般有以下几种情况: 虚拟机栈和本地方法栈溢出 StackOverflowError: 线程请求的栈深度大于虚拟机所允许的最大深度

记一次解决tomcat自动关闭的bug

£可爱£侵袭症+ 提交于 2019-11-27 08:37:45
最近一个运行了4年的javaee web项目,经常接到客户反馈系统无法打开。登录服务器查看服务,发现是tomcat自动关闭了。基本是3到4天发生一次。 运维人员开始以为是其他服务杀死了tomcat服务,没放在心上,解决方法就是直接重启tomcat。 最终捅了篓子,运维人员被客户投诉,扣了一个月的绩效。 解决这个bug兜兜转转来到了我这里。既然接到任务,那就开干,没有解决不了的bug。 系统的运行环境如下: tomcat6.0 32位jdk7.0 window server2003 32位,32G内存。 查看日志,如果tomcat闪崩,都会在tomcat的bin目录下生成以"hs_err"开头的日志文件。打开最新的日志文件,首先看到的是下面一段话: # There is insufficient memory for the Java Runtime Environment to continue. # Native memory allocation (malloc) failed to allocate 32756 bytes for ChunkPool::allocate # Possible reasons: # The system is out of physical RAM or swap space # In 32 bit mode, the process size

Java回收机制概述

烂漫一生 提交于 2019-11-27 05:49:27
Java技术体系中所提倡的 自动内存管理 最终可以归结为自动化地解决了两个问题:给对象分配内存 以及 回收分配给对象的内存,而且这两个问题针对的内存区域就是Java内存模型中的 堆区。 垃圾回收机制的引入可以有效的防止内存泄露、保证内存的有效使用,也大大解放了Java程序员的双手,使得他们在编写程序的时候不再需要考虑内存管理。本文着重介绍了判断一个对象是否可以被回收的两种经典算法,并详述了四种典型的垃圾回收算法的基本思想及其直接应用——垃圾收集器,最后结合内存回收策略介绍了内存分配规则。 本文内容是基于 JDK 1.6 的,不同版本虚拟机之间也许会有些许差异,但不影响我们对JVM垃圾回收机制的整体把握和了解。 一、垃圾回收机制的意义 在上篇《 JVM内存模型概述 》中知道:JVM 内存模型一共包括三个部分:堆 ( Java代码可及的 Java堆 和 JVM自身使用的方法区)、栈 ( 服务Java方法的虚拟机栈 和 服务Native方法的本地方法栈 ) 和 保证程序在多线程环境下能够连续执行的程序计数器。特别地,我们当时就提到Java堆是进行垃圾回收的主要区域,故其也被称为GC堆;而方法区也有一个不太严谨的表述,就是永久代。总的来说,堆 (包括Java堆 和 方法区)是 垃圾回收的主要对象,特别是Java堆。   实际上,Java技术体系中所提倡的 自动内存管理

jvm的stack和heap,JVM内存模型,垃圾回收策略,分代收集,增量收集(转)

核能气质少年 提交于 2019-11-27 01:37:10
深入 Java 虚拟机: JVM 中的 Stack 和 Heap (转自: http://www.cnblogs.com/laoyangHJ/archive/2011/08/17/gc-Stack.html ) 在JVM中,内存分为两个部分,Stack(栈)和Heap(堆),这里,我们从JVM的内存管理原理的角度来认识Stack和Heap,并通过这些原理认清 Java 中静态方法和静态属性的问题。   一般,JVM的内存分为两部分:Stack和Heap。   Stack(栈)是JVM的内存指令区。Stack管理很简单,push一定长度字节的数据或者指令,Stack指针压栈相应的字节位移;pop一定字节长度数据或者指令,Stack指针弹栈。Stack的速度很快,管理很简单,并且每次操作的数据或者指令字节长度是已知的。所以 Java 基本数据类型, Java 指令代码,常量都保存在Stack中。   Heap(堆)是JVM的内存数据区。Heap 的管理很复杂,每次分配不定长的内存空间,专门用来保存对象的实例。在Heap 中分配一定的内存来保存对象实例,实际上也只是保存对象实例的属性值,属性的类型和对象本身的类型标记等,并不保存对象的方法(方法是指令,保存在Stack中),在Heap 中分配一定的内存保存对象实例和对象的序列化比较类似。而对象实例在Heap 中分配好以后

JVM老年代和新生代的比例

有些话、适合烂在心里 提交于 2019-11-25 23:16:59
在 Java 中,堆被划分成两个不同的区域:新生代 ( Young )、老年代 ( Old )。新生代 ( Young ) 又被划分为三个区域:Eden、From Survivor、To Survivor。 这样划分的目的是为了使 JVM 能够更好的管理堆内存中的对象,包括内存的分配以及回收。 堆的内存模型大致为: 从图中可以看出: 堆大小 = 新生代 + 老年代。其中,堆的大小可以通过参数 –Xms、-Xmx 来指定。 默认的,新生代 ( Young ) 与老年代 ( Old ) 的比例的值为 1:2 ( 该值可以通过参数 –XX:NewRatio 来指定 ),即:新生代 ( Young ) = 1/3 的堆空间大小。老年代 ( Old ) = 2/3 的堆空间大小。其中,新生代 ( Young ) 被细分为 Eden 和 两个 Survivor 区域,这两个 Survivor 区域分别被命名为 from 和 to,以示区分。 默认的,Eden : from : to = 8 : 1 : 1 ( 可以通过参数 –XX:SurvivorRatio 来设定 ),即: Eden = 8/10 的新生代空间大小,from = to = 1/10 的新生代空间大小。 JVM 每次只会使用 Eden 和其中的一块 Survivor 区域来为对象服务,所以无论什么时候,总是有一块