嗨两个问题,如果我可以学习?
- 在 Scala 或 Java 中导致堆空间不足的可能原因有哪些?
- 有避免它的最佳做法吗?
当您启动一个Java
进程时,它会设置一个默认的 maxHeapMemory,即该进程可以使用的最大堆内存。您可以传递一个命令行参数来增加它,但根据您的应用程序的内存使用情况,它可能仍然不够。内存泄漏是另一个问题,它可能会耗尽您的内存(不释放它以进行垃圾收集),这可能会导致内存不足问题。设置开始分配的堆内存和允许的最大堆内存取决于您的应用程序及其内存使用情况,您可以为此判断、测试和分析您的应用程序(内存使用情况)。
您必须首先了解您的堆内存。另一方面,您的应用程序可能存在内存泄漏。您可以帮助 JVM 的垃圾收集器的一种方法是取消您的引用。试试看这个问题Understanding Java Memory Management
我们可以通过转到控制面板>Java>Java 选项卡>查看>Java 运行时环境> 来分配 maxHeapmemory 大小
Assisgn RunTime 参数大小根据要求例如:-Xmx4000m
1) 最大堆内存量。解决方案:
-Xmx // maximal amount of heap memory parameter
-d32 // 32-bit VM
2)堆内存永久代空间。解决方案:
-XX:MaxPermSize
3) 内存泄漏。解决方案:
jVisualVM
(../java/bin/jvisualvm )进行分析FindBugs
工具或类似物4)System.gc
建议执行垃圾收集器。
可以通过监视内存消耗来处理 OutOfMemoryError Runtime.freeMemory
,Runtime.maxMemory
和Runtime.totalMemory
,并在您的应用程序中以对内存消耗要求较低的模式执行System.gc
切换(例如将数据交换到磁盘或数据库)。一个关键决定(在我的用例中)是实现一个函数,如果内存不足,对于特定线程,每个时间间隔执行 System.gc 不超过一次。
当然,一个系统可以很容易地自行进行交换,但它会更慢,而且通常你在一台机器上拥有多个生产中的 VM。
在使用范围内定义对象大大减少了进行大量内存管理的需要,并简化了您的编码方式。
经验法则 - 与全局对象相比,本地对象通常是一个更好的主意。
class AddThem{
private int sumGlobal = 0; //Usually bad idea for long lived processes
public int addThem(int a, int b){
int sumLocal;
sumLocal = a + b
return sumLocal;
}
}
这可能被简化了太多,但如果 sumGlobal 是对象的集合......它们会保留在内存中,直到 AddThem 的实例被垃圾收集。sumLocal 遭受了不同的命运,在这种情况下更好。
Scala 特有的这个问题并不多。这几乎只是一个 JVM 问题。不平凡的程序(Scala或Java)超过默认的 JVM 堆限制是很常见的。
Scala 特有的事实是,每个函数字面量和名称参数都被编译为一个单独的类。在 Scala 中创建函数文字时很容易不知道,因为它使使用它们变得如此容易,就像函数式编程的重点一样。
So, in large Scala programs this can sometimes lead to an exhaustion of the Perm-Gen space where classes are loaded (as opposed to the "ordinary" heap spaces from which instances of user-defined classes are allocated). The JVM has separate options for setting the Perm Gen size. In the "stock" Oracle JVM it's -XX:MaxPermSize=###u
(where u
is a units character, k
for kilo-, m
for mega- and g
for giga-bytes).