我们有一个长期存在的服务器进程,很快就需要大量的RAM.我们看到,一旦JVM从操作系统获得内存,它就永远不会将其返回给操作系统.我们如何要求JVM将堆内存返回给操作系统?
通常,这些问题的接受答案是使用
-XX:MaxHeapFreeRatio和-XX:MinHeapFreeRatio.(参见例如
1,2,3,4).但是我们像这样运行java:
java -Xmx4G -XX:MaxHeapFreeRatio=50 -XX:MinHeapFreeRatio=30 MemoryUsage
Run Code Online (Sandbox Code Playgroud)
仍然在VisualVM中看到这个:
显然,JVM并不尊重,-XX:MaxHeapFreeRatio=50因为heapFreeRatio非常接近100%而且远不及50%.无需点击"执行GC"即可将内存返回给操作系统.
MemoryUsage.java:
import java.util.ArrayList;
import java.util.List;
public class MemoryUsage {
public static void main(String[] args) throws InterruptedException {
System.out.println("Sleeping before allocating memory");
Thread.sleep(10*1000);
System.out.println("Allocating/growing memory");
List<Long> list = new ArrayList<>();
// Experimentally determined factor. This gives approximately 1750 MB
// memory in our installation.
long realGrowN = 166608000; //
for (int i = 0 ; i < realGrowN …Run Code Online (Sandbox Code Playgroud) 我理解如何struct在堆上创建使用malloc.正在寻找struct关于在堆栈上创建一个C而不是所有文档的一些文档.似乎只谈论堆上的结构创建.
在Haskell中进行编程时(特别是在解决Project Euler问题时,其中次优解决方案往往会对CPU或内存需求造成压力)我经常感到困惑,为什么程序的行为方式如此.我看一下配置文件,尝试引入一些严格,选择另一种数据结构,...但主要是它在黑暗中摸索,因为我缺乏良好的直觉.
此外,虽然我知道如何实现Lisp,Prolog和命令式语言,但我不知道实现一种懒惰的语言.我也有点好奇.
因此,我想了解更多关于从程序源到执行模型的整个链.
我想知道的事情:
应用了哪些典型的优化?
当有多个评估候选者时,执行顺序是什么(虽然我知道它是从所需的输出驱动的,但是在首先评估A然后B之后可能仍然存在很大的性能差异,或者首先评估B以检测到您不需要一点都不)
thunk如何代表?
如何使用堆栈和堆?
什么是CAF?(分析表明有时热点在那里,但我没有线索)
我的应用程序目前消耗相当多的内存,因为它正在运行物理模拟.问题是始终如一,在第51次模拟时,java会抛出一个错误,通常是因为堆空间内存不足(我的程序最终运行了数千次模拟).
无论如何我不能只增加堆空间但是修改我的程序,以便在每次运行后清除堆空间,以便我可以运行任意数量的模拟?
谢谢
-编辑-
多谢你们.事实证明,模拟器软件在每次运行后都没有清除信息,我将这些运行全部存储在arraylist中.
在 K&R(C 编程语言第 2 版)第 5 章中,我阅读了以下内容:
首先,在某些情况下可以比较指针。如果
p和q指向同一个数组的成员,则关系一样==,!=,<,>=,等正常工作。
这似乎意味着只能比较指向同一数组的指针。
但是,当我尝试此代码时
char t = 't';
char *pt = &t;
char x = 'x';
char *px = &x;
printf("%d\n", pt > px);
Run Code Online (Sandbox Code Playgroud)
1 被打印到屏幕上。
首先,我认为我会得到 undefined 或某种类型或错误,因为pt和px没有指向同一个数组(至少在我的理解中)。
也是pt > px因为两个指针都指向存储在栈上的变量,栈向下增长,所以内存地址t大于x?为什么pt > px是真的?
当 malloc 被引入时,我变得更加困惑。 同样在第 8.7 章的 K&R 中写到以下内容:
然而,仍然存在一种假设,即
sbrk可以有意义地比较指向由 返回的不同块的指针。仅允许在数组内进行指针比较的标准并不能保证这一点。因此,这个版本的malloc仅在一般指针比较有意义的机器之间是可移植的。
将指向堆上 malloced …
我最近在我的服务器上使用PySpark与Ipython一起使用24个CPU和32GB RAM.它只能在一台机器上运行.在我的过程中,我想收集大量数据,如下面的代码所示:
train_dataRDD = (train.map(lambda x:getTagsAndText(x))
.filter(lambda x:x[-1]!=[])
.flatMap(lambda (x,text,tags): [(tag,(x,text)) for tag in tags])
.groupByKey()
.mapValues(list))
Run Code Online (Sandbox Code Playgroud)
当我做
training_data = train_dataRDD.collectAsMap()
Run Code Online (Sandbox Code Playgroud)
它给了我outOfMemory错误.Java heap Space.此外,我在此错误后无法对Spark执行任何操作,因为它失去了与Java的连接.它给出了Py4JNetworkError: Cannot connect to the java server.
看起来堆空间很小.如何将其设置为更大的限制?
编辑:
我在跑步之前尝试过的事情:
sc._conf.set('spark.executor.memory','32g').set('spark.driver.memory','32g').set('spark.driver.maxResultsSize','0')
我按照此处的文档更改了spark选项(如果你执行ctrl-f并搜索spark.executor.extraJavaOptions):http://spark.apache.org/docs/1.2.1/configuration.html
它说我可以通过设置spark.executor.memory选项来避免OOM.我做了同样的事情,但似乎没有工作.
我正在运行一个创建和忘记大量对象的应用程序,长现有对象的数量确实增长缓慢,但与短期对象相比,这是非常少的.这是一个具有高可用性要求的桌面应用程序,需要每天24小时开启.大部分工作都是在一个线程上完成的,这个线程只会使用它可以获得它的所有CPU.
在过去,我们在重负载下看到了以下内容:使用的堆空间缓慢上升,因为垃圾收集器收集的内存少于新分配的内存量,使用的堆大小缓慢增长并最终接近指定的最大堆.此时,垃圾收集器将大量启动,并开始使用大量资源来防止超过最大堆大小.这会减慢应用程序的速度(轻松放慢10倍),此时GC大部分时间会在几分钟后成功清理垃圾或者失败并扔掉OutOfMemoryException,两者都不是真的可以接受.
使用的硬件是四核处理器,至少4GB内存运行64位Linux,如果需要,我们可以使用所有这些.目前,该应用程序大量使用单个核心,该核心大部分时间都在运行单个核心/线程.其他核心大多是空闲的,可用于垃圾收集.
我有一种感觉,垃圾收集器应该在早期阶段更积极地收集,远在它耗尽内存之前.我们的应用程序没有任何吞吐量问题,低暂停时间要求比吞吐量更重要,但远不如不接近最大堆大小重要.如果单个繁忙线程仅以当前速度的75%运行是可以接受的,只要这意味着垃圾收集器可以跟上创建的步伐.简而言之,性能的稳定下降优于我们现在看到的突然下降.
我已经仔细阅读了Java SE 6 HotSpot [tm]虚拟机垃圾收集调整,这意味着我很好地理解了这些选项,但是我仍然觉得很难选择正确的设置,因为我的要求与文中讨论的内容有点不同.
目前我正在使用带有选项的ParallelGC -XX:GCTimeRatio=4.这比时间比的默认设置好一点,但我感觉GC允许运行的设置比它更多.
为了监控,我主要使用jconsole和jvisualvm.
我想知道您为上述情况推荐的垃圾收集选项.另外,我可以看看哪个GC调试输出更好地理解瓶颈.
编辑: 我理解这里有一个非常好的选择是创造更少的垃圾,这是我们真正考虑的事情,但是我想知道我们如何通过GC调整解决这个问题,因为这是我们可以更容易做到的事情并且滚动比更改大量源代码更快.此外,我已经运行了不同的内存分析器,我了解垃圾的用途,我知道它包含可以收集的对象.
我在用:
java version "1.6.0_27-ea"
Java(TM) SE Runtime Environment (build 1.6.0_27-ea-b03)
Java HotSpot(TM) 64-Bit Server VM (build 20.2-b03, mixed mode)
Run Code Online (Sandbox Code Playgroud)
使用JVM参数:
-Xmx1024M and -XX:GCTimeRatio=4
Run Code Online (Sandbox Code Playgroud)
编辑回复Matts注释: 大多数内存(和cpu)用于构建表示当前情况的对象.当情况迅速变化时,其中一些将被立即丢弃,如果没有更新进入一段时间,其他一些将具有中等寿命.
这个问题一直困扰着我.我一直认为C++应该被设计成使"删除"操作符(没有括号)即使使用"new []"运算符也能工作.
在我看来,写这个:
int* p = new int;
Run Code Online (Sandbox Code Playgroud)
应该相当于分配1个元素的数组:
int* p = new int[1];
Run Code Online (Sandbox Code Playgroud)
如果这是真的,"删除"运算符可能总是删除数组,我们不需要"delete []"运算符.
是否有任何理由在C++中引入"delete []"运算符?我能想到的唯一原因是分配数组的内存占用量很小(你必须在某处存储数组大小),因此区分"delete"与"delete []"是一个很小的内存优化.
我想知道是否有一种很好的方法可以找到导致堆损坏错误的源代码,给定在Visual Studio中分配的堆块"外部"写入的数据的内存地址;
专用(0008)免费列表元素26F7F670大小错误(死)
(试着写下关于如何查找内存错误的一些注释)
提前致谢!
提出这个问题时,Docker看起来很新,不能在网上找到这个问题的答案.我找到的唯一一个地方就是这篇文章,其中作者说这很难,就是这样.
heap-memory ×10
java ×5
c ×2
apache-spark ×1
c++ ×1
debugging ×1
docker ×1
ghc ×1
haskell ×1
memory ×1
optimization ×1
physics ×1
pointers ×1
pyspark ×1
stack-memory ×1