【问题标题】:run a jar command line with maximum resources运行具有最大资源的 jar 命令行
【发布时间】:2019-03-17 01:09:27
【问题描述】:

我正在尝试运行一个可以处理 100M 行记录的 jar。我达到了 GC 上限。它适用于10M,没有问题。

我知道最好的办法是找到溢出发生的位置

我想尝试一次在服务器上运行 jar,为其提供堆内存、GC 内存等方面的最大资源。

我尝试使用 -xms 和 -xmc 运行我的 jar

java -Xmx256m -Xmc256m -jar myapp.jar //类似的东西

我想知道如何以尽可能多的资源运行,因为我不将此服务器用于任何其他应用程序。

我也试过用这个命令多线程

java -jar -Xmx30024m -XX:ParallelGCThreads=12000 myapp.jar

但我不确定这能起到多大作用。

有人可以建议我如何通过在命令行中进行一些有限更改来克服此 GC 错误,以使用实例中的最大资源。

【问题讨论】:

  • 它已经在使用可能的最大资源死于该异常之前,您真的将堆设置为 30GB,但这还不够吗?也将该数字ParallelGCThreads 降至 12000 以下
  • 您确定您尝试加载的记录都需要同时在内存中吗?如果不尝试按顺序加载它们,即一次加载 100 万个。此外,如果加载 100M 记录所需的内存超过服务器上的资源,那么 JVM 参数将无济于事。

标签: java memory-management jar out-of-memory heap-memory


【解决方案1】:

问题不在于垃圾收集器,GC 速度很快。只有当您已经拥有no memory left 时,GC 才会抛出此错误。 30GB 绝对足够 100M 记录,除非记录很大。每条记录的大小是多少?我会尝试:

1) 确保您拥有 64 位 Java,如果您不小心使用了 32 位 Java,请重新运行您的代码

2) 将对象拉出最里面的循环/优化对象分配,即:使用 .clear();不要创建一个新数组。将执行大量操作的最内层循环拆分为几个不同的循环,每次迭代需要分配的对象数量较少。

3) 尝试使您的工作增量,即使用合并排序而不是快速排序。这样,您可以将工作分配给 10M 记录输入的多个实例,并在合并到 100M 答案之前保存每个增量进度。

4) 用 C/C++/Rust 对其进行编码,因此它使用堆栈而不是堆来存储临时变量。如果您不在 Java 版本的最内层循环中的任何地方使用“new”,那么您可能需要更多地压缩数据使用。使用 5M、10M、15M 记录对内存使用情况进行基准测试,以获得每条记录的每字节影响(通过这三个点的线的斜率),看看你是否可以想象如果你有的话,可以用更少的字节保存每条记录以系统语言单独控制每个字节(并查看该值是否仍小于您拥有的 RAM 量)。

5) 如果你的记录很大(>1kb),你肯定要缓存。使用 getter 来访问每条记录,而不是直接从数组中访问,并限制内存使用。让 getter 访问一个简单的 100M 引用数组,并将其中 90M 限制为 NULL。如果在已经使用 10M 的情况下尝试访问新记录,则在访问磁盘之前将随机/很少使用的现有记录设置为 NULL,缓存值并返回请求的记录。确保您的算法非常适合这种缓存(比建议 3 更宽松的要求,但原则上相同)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-13
    • 2016-10-09
    • 1970-01-01
    • 2011-06-04
    • 2020-12-24
    • 2019-04-01
    • 1970-01-01
    相关资源
    最近更新 更多