通常,当应用程序尝试创建具有负大小的数组时会出现此错误。见下面的例子。
它的一般 java 错误。在你的情况下,我怀疑这是由
Dataset<Info> infos = spark.read().json("data.json").as(Encoders.bean(Info.class));
System.out.println(infos.rdd().count());
您可以通过打印完整的堆栈跟踪来查看此代码在哪种情况下,它的负初始化。
import java.util.*;
import java.io.*;
public class Stacktest
{
public static void main(String args[])throws IOException
{
int c[]=new int[-2];
Scanner in=new Scanner(new InputStreamReader(System.in));
int b=in.nextInt();
int a[]=new int[b];
}
}
output:
-2
Exception in thread "main" java.lang.NegativeArraySizeException
at Stacktest.main(Stacktest.java:10)
注意: 其中一个用例是Kryo
与 apache spark 一起使用序列化......当它可能发生/修复时,如下所示......
非常大的对象图
参考限值
Kryo
将引用存储在基于int
数组的映射中。由于 Java 数组索引仅限于Integer.MAX_VALUE
,因此序列化大型(> 10 亿)对象可能会导致
java.lang.NegativeArraySizeException
.
此问题的解决方法是禁用 Kryo 的参考跟踪,如下所示:
Kryo kryo = new Kryo();
kryo.setReferences(false);
或者像spark.kryo.refferenceTrackingEnabled
= false
inspark-default.conf
或sparkConf
object 这样的属性,如果你想以编程方式设置它..
Spark 文档说
spark.kryo.referenceTracking
默认值true
是否在使用 Kryo 序列化数据时跟踪对同一对象的引用,如果您的对象图有循环,这是必要的,如果它们包含同一对象的多个副本,则对提高效率很有用。如果您知道情况并非如此,可以禁用以提高性能。