最大堆

JVM实用参数(四)内存调优

混江龙づ霸主 提交于 2020-04-08 13:15:35
理想的情况下,一个Java程序使用JVM的默认设置也可以运行得很好,所以一般来说,没有必要设置任何JVM参数。然而,由于一些性能问题(很不幸的是,这些问题经常出现),一些相关的JVM参数知识会是我们工作中得好伙伴。在这篇文章中,我们将介绍一些关于JVM内存管理的参数。知道并理解这些参数,将对开发者和运维人员很有帮助。 所有已制定的HotSpot内存管理和垃圾回收算法都基于一个相同的堆内存划分:新生代(young generation)里存储着新分配的和较年轻的对象,老年代(old generation)里存储着长寿的对象。在此之外,永久代(permanent generation)存储着那些需要伴随整个JVM生命周期的对象,比如,已加载的对象的类定义或者String对象内部Cache。接下来,我们将假设堆内存是按照新生代、老年代和永久代这一经典策略划分的。然而,其他的一些堆内存划分策略也是可行的,一个突出的例子就是新的G1垃圾回收器,它模糊了新生代和老年代之间的区别。此外,目前的开发进程似乎表明在未来的HotSpot JVM版本中,将不会区分老年代和永久代。 -Xms and -Xmx (or: -XX:InitialHeapSize and -XX:MaxHeapSize) -Xms和-Xmx可以说是最流行的JVM参数,它们可以允许我们指定JVM的初始和最大堆内存大小。一般来说

Leetcode 480.滑动窗口中位数

。_饼干妹妹 提交于 2020-03-27 18:28:03
滑动窗口中位数 中位数是有序序列最中间的那个数。如果序列的大小是偶数,则没有最中间的数;此时中位数是最中间的两个数的平均数。 例如: [2,3,4],中位数是 3 [2,3],中位数是 (2 + 3) / 2 = 2.5 给出一个数组 nums,有一个大小为 k 的窗口从最左端滑动到最右端。窗口中有 k 个数,每次窗口移动 1 位。你的任务是找出每次窗口移动后得到的新窗口中元素的中位数,并输出由它们组成的数组。 例如: 给出 nums = [1,3,-1,-3,5,3,6,7],以及 k = 3。 窗口位置 中位数 --------------- ----- [1 3 -1] -3 5 3 6 7 1 1 [3 -1 -3] 5 3 6 7 -1 1 3 [-1 -3 5] 3 6 7 -1 1 3 -1 [-3 5 3] 6 7 3 1 3 -1 -3 [5 3 6] 7 5 1 3 -1 -3 5 [3 6 7] 6 因此,返回该滑动窗口的中位数数组 [1,-1,-1,3,5,6]。 提示: 假设k是合法的,即:k 始终小于输入的非空数组的元素个数. 解题思想 题目会给一个数组,和一个滑动窗口的大小K,让你找出当这个窗口滑动的过程中,这个K的窗口内的中位数分别是多少? 最naive的方式就是在k个窗口内排序就好,这里不解释(因为开销很大啊,(n-k+1) * (k*log(k)

java各种排序算法及实现

不羁岁月 提交于 2020-03-26 00:18:44
3 月,跳不动了?>>> 先来看看8种排序之间的关系: 下图是各种排序的比较: 1, 直接插入排序 (1)基本思想:在要排序的一组数中,假设前面(n-1) [n>=2] 个数已经是排 好顺序的,现在要把第n个数插到前面的有序数中,使得这n个数 也是排好顺序的。如此反复循环,直到全部排好顺序。 在插入算法中,如果有一个最小的数在数组的最后面,用插入算法就会从最后一个 位置移动到第一个。 (2)实例 package cglib; public class StringNumber { public static void insertSort(int[] a) { if (a == null || a.length < 2) { return; } int length=a.length; //数组长度 int j; //当前值的位置 int i; //指向j前的位置 int key; //当前要进行插入排序的值 //从数组的第二个位置开始遍历值 for(j=1;j<length;j++){ key=a[j]; i=j-1; System.out.println(" 将i="+i); //a[i]比当前值大时,a[i]后移一位,空出i的位置,好让下一次循环的值后移 while(i>=0 && a[i]>key){ System.out.println("进 i="+i); a[i+1]

优先队列&最大堆

半腔热情 提交于 2020-03-16 20:21:21
1. 采用什么数据结构存储 普通非顺序线性结构 添加数据 O(1) 获取元素 O(n) 利用树形结构,实现一个堆 父元素比左右子树元素的值都大 堆的节点层次不能决定他的大小(不一定层次越低值越大)、 最大堆是一个完全二叉树 2.最大堆的实现-数组 用数组实现可以不使用0号位置 parentIdex = i / 2 leftChild = i / 2 rightChild = i / 2 + 1 2.1 利用自定义数组实现存储 此处可替换为原生数组 public class MaxHeap < E extends Comparable < E > > { private Array < E > data ; public MaxHeap ( int capacity ) { data = new Array < > ( capacity ) ; } public MaxHeap ( ) { data = new Array < > ( ) ; } // 返回堆中的元素个数 public int size ( ) { return data . getSize ( ) ; } // 返回一个布尔值, 表示堆中是否为空 public boolean isEmpty ( ) { return data . isEmpty ( ) ; } // 返回完全二叉树的数组表示中

数据结构——堆排序

北战南征 提交于 2020-03-05 02:43:18
堆排序总结 堆排序思想:最大堆的堆顶元素是全部数据中的最大值,输出这个值 。再将剩余元素整理成新的最大堆,此时堆顶元素有时又是剩余元素 的最大值,再输出这个值。继续这个过程,每次输出堆顶元素,并将 剩余元素整理成新的最大堆再输出... 堆排序要解决的几个问题 1:如何将数据排列成堆的形式——初始堆的建立 2:输出堆顶元素后,剩余元素如何再整理成新的堆——堆的整理 3:输出元素放在什么位置 预备知识: 1: 堆中的元素存储在一个数组中,根据堆中的各元素之间具有 有序性关系,可以使用二叉树的方式来表示一个堆。因为各元素从前 至后存放在数组的钱n 个单元中,所以所画的二叉树实际上是一颗完全 二叉树 2: 所以根据完全二叉树的性质,数组前一半的数据都是分值节点,后一半 的数据都是叶子节点 3: 即如果有七个数,分别占据数组的a[1]-a[7],那么7/2=3,所以a[1], a[2],a[3]为分支节点,剩下的为叶子节点 4: a[i]的左儿子为a[i*2],右儿子为a[i*2+1],如a[1]的左右儿子分别为 a[2]与a[3]。(这有赖于数组从a[0]开始,还是从a[1]开始) 建堆的过程: 见代码,见实例图 /*********************************************************/ /*数组从下标1开始*/ #include

数据结构(第五章)

折月煮酒 提交于 2020-02-21 05:18:42
树下 第一讲 一.堆 什么是堆? 在讲堆之前,我们先看看什么是优先队列。 优先队列:是一种特殊的队列,从名称上看,优先,顾名思义,取出的元素是按照一定的优先级出队的,而不是元素进入队列的先后顺序。 优先队列的完全二叉树表示 堆的两个特性: 结构性 :用数组表示的完全二叉树。 有序性 :任一结点的关键字是其子树所有结点的最大值(或最小值)。 由最大值和最小值我们可以引出一个新概念“最大堆”“最小堆” 最大堆:每个结点的元素值不小于其子结点的元素值。 最小堆:每个结点的元素值不大于其子结点的元素值。 主要在最大堆的操作上面,因为最大堆会了,最小堆自然就不成问题了 最大堆的创建 typedef struct HeapStruct * MaxHeap ; struct HeapStruct { ElementType * Elements [ ] ; //存储堆元素 int Size ; //堆元素个数 int Capacity ; //堆的最大容量 } MaxHeap Create ( int MaxSize ) { MaxHeap H = malloc ( sizeof ( struct Heapstruct ) ) ; H -> Elements = malloc ( ( MaxSize + 1 ) * sizeof ( sizeof ( ElementType ) ) ; H ->

如何确定默认的Java堆大小?

…衆ロ難τιáo~ 提交于 2020-02-13 03:44:29
如果我从Java命令行中省略了 -Xmxn 选项,那么将使用默认值。 根据 Java文档 “根据系统配置在运行时选择默认值” 哪些系统配置设置会影响默认值? #1楼 Java 6更新18中 对此进行了更改。 假设我们拥有超过 1 GB 的物理内存(如今非常普遍),则它始终是您物理内存的1/4。 #2楼 埃内斯托是对的。 根据他发布的链接[1]: 更新了客户端JVM堆配置 在客户端JVM中... 默认的最大堆大小是物理内存的一半,最大物理内存大小为192 MB,否则为四分之一,最大物理内存大小为1 GB。 例如,如果您的计算机具有128兆字节的物理内存,则最大堆大小为64兆字节,并且大于或等于1千兆字节的物理内存将导致最大堆大小为256兆字节。 除非您的程序创建了足够多的对象来要求它,否则JVM实际上并没有使用最大堆大小。 在JVM初始化期间分配了一个较小的值,称为初始堆大小。 ... ... 服务器JVM堆配置的人机工程学与客户端相同,不同之处在于 32位JVM的默认最大堆大小为1 GB ,对应于4 GB的物理内存大小,而 64位JVM 的默认最大堆大小为32 GB ,对应于到128 GB的物理内存大小。 [1] http://www.oracle.com/technetwork/java/javase/6u18-142093.html #3楼 在Windows上

面试题41:数据流中的中位数

有些话、适合烂在心里 提交于 2020-02-07 22:16:56
1、题目描述:    如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。 2、思路: 看到这道题很自然的想到常规解法,对数组进行排序,也就是说只要插入一个数据,就对数组进行一次排序,就要移动后边的数字,因此插入数据的时间复杂度为o(n),而从排序数组中取出中位数的时间复杂度为O(1)。这种方法比较显然,还不是最终解法。   而另一种解法就是用自平衡的二叉搜索树(AVL)树,通常AVL树的平衡因子是左右子树的高度差。可以稍作修改,把AVL的平衡因子改为左右子树的节点数目之差。这样插入新的节点的时间复杂度为O(logn),而取出中位数的时间复杂度为O(1)。而AVL树是没有库函数的,因此不好实现。   最终的解法:可以先观察如下数组 N1 N2 ...... Nm Nm+1 .......N2m N2m+1 N1 N2 ...... Nm Nm+1 .......N2m   上边的数组元素个数为奇数个,中位数是Nm+1   下边的为偶数个元素,中位数是Nm+Nm+1除以2   无论是奇数个元素还是偶数个,整个数组被分成了两部分

POJ 1442 优先队列

谁都会走 提交于 2020-02-07 02:09:14
题意:有一些ADD和GET操作。n次ADD操作,每次往序列中加入一个数,由ADD操作可知序列长度为1-n时序列的组成。GET操作输入一个序列长度,输出当前长度序列第i大的元素的值。i初始为0,每次GET操作i先加1。给出的GET操作输入非降。 思路:求长度为k的序列的第i大元素。优先队列维护最大堆和最小堆分别存放前i-1大的元素和第i-第k大的元素。将当前序列的元素压入最小堆,如果最小堆的最小数大于最大堆的最大数则进行交换,保证最大堆中的所有数小于最小堆。因为i值每进行一次自增1,所以每次GET操作后将最小堆中的最小数弹出存入最大堆。 #include<cstdio> #include<queue> using namespace std; priority_queue<int> bigque; priority_queue<int, vector<int> ,greater<int> > smallque; int num[30010]; int main() { int n,m,x; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&num[i]); int k=1; for(int i=1;i<=m;i++) { scanf("%d",&x); while(k<=x) { smallque.push(num[k]);

二叉堆-19王祥力

牧云@^-^@ 提交于 2020-02-07 01:42:36
二叉堆是一种特殊的堆,二叉堆是完全二元树(二叉树))。二叉堆有两种:最大堆和最小堆。最大堆:父结点的键值总是大于或等于任何一个子节点的键值;最小堆:父结点的键值总是小于或等于任何一个子节点的键值。 二叉堆的作用就是:增加存储效率。 二叉堆一般用数组来表示。例如,根节点在数组中的位置是0,第n个位置的子节点分别在2n+1和 2n+2。因此,第0个位置的子节点在1和2,1的子节点在3和4。以此类推。这种存储方式便於寻找父节点和子节点。 最大堆的性质是:每个节点都大于等于它的两个子节点。类似的,最小堆的性质是:每个节点都小于等于它的子节点。 两种堆核心思路都是一样的. 对于一个最大堆,根据其性质,显然堆顶,也就是 arr[1] 一定是所有元素中最大的元素。 当其子节点比其大是它就没有资格去做父节点了,这时它应该下台,让比它大的来做父节点。 如图: 让我一段代码来实现: int x; scanf("%d",&x); a[n]=x; int now=n; while(now) { int s=(now-1)/2; if(a[s]<a[now]) { int t=a[s]; a[s]=a[now]; a[now]=t; } else break; now=s; } 上面提到的是添加元素的一种方法,此外还有删除,修改元素。 删除元素 删除元素的过程类似,只不过添加元素是"向上冒",而删除元素是