定义一个巨大的全局 ImmutableList 常量的优雅方式(超出堆栈大小限制)
Elegant way to define a huge global ImmutableList constant (beyond stack size limitation)
我正在尝试定义一个全局常量 ImmutableList,它对于默认堆栈大小限制来说太大了,我想知道除了传递积极的 Xss32M
标志之外是否还有其他方法可以解决这个问题至 java
.
这是代码片段:
import com.google.common.collect.ImmutableList;
import util.FixedRowDefinition;
import java.util.List;
public class FancyConstants {
public static final List<Person> student_list = new ImmutableList.Builder<Person>()
.add(new Person("Amy",12,56))
.add(new Person("Tom",26,79))
.........
.add(...).build()
/* More similar definitions; could be very long */
}
像上面这样大概有2000行,我猜class炸毁的原因是每个元素都是一个对象(虽然很精简)。
有没有一种方法可以让我在 Java 中定义 student_list
,这样它就不会像我目前观察到的那样导致 Whosebug
错误?
您观察到的 Whosebug 错误是由于构建器模式中的调用链造成的。您可以通过在静态初始化程序中添加一个变量来避免它:
public class FancyConstants {
public static final List<Person> student_list;
static {
ImmutableList.Builder<Person> builder = new ImmutableList.Builder<Person>();
builder.add(new Person("Amy",12,56));
builder.add(new Person("Tom",26,79));
.........
/* More similar definitions; could be very long */
builder.add(...);
student_list = builder.build();
}
}
显然,这不是很优雅,但它修复了 Stack Overflow 错误。
您可以通过从文件中读取数据来改进这种方法,该文件可以作为资源嵌入到您的 Java 程序中。
This Q&A 解释了如何从嵌入式资源中读取。由于您的程序拥有资源的内容,因此您可以使用少量代码填充 builder
,并且几乎没有错误检查。
要回答您原来的问题,您可以使用 -J
选项将 JVM 选项传递给 javac
。例如。我采用了您的代码模板,创建了 3600 次调用链,并使用 -J-Xss10m
.
成功编译了 javac
但是虽然这足以编译和 运行 程序(运行ning 不需要大的堆栈大小),但此源代码仍然会在 IDE 中引起问题或奇怪的行为,而这些问题不是配置为使用更大的堆栈大小处理此源代码。递归解析和处理源代码,太常见了。
此外,编译代码的大小接近方法大小限制,因此没有太多空间容纳更大的列表。所以我只能赞成 建议转向使用资源来处理这种大小的常量列表。
我正在尝试定义一个全局常量 ImmutableList,它对于默认堆栈大小限制来说太大了,我想知道除了传递积极的 Xss32M
标志之外是否还有其他方法可以解决这个问题至 java
.
这是代码片段:
import com.google.common.collect.ImmutableList;
import util.FixedRowDefinition;
import java.util.List;
public class FancyConstants {
public static final List<Person> student_list = new ImmutableList.Builder<Person>()
.add(new Person("Amy",12,56))
.add(new Person("Tom",26,79))
.........
.add(...).build()
/* More similar definitions; could be very long */
}
像上面这样大概有2000行,我猜class炸毁的原因是每个元素都是一个对象(虽然很精简)。
有没有一种方法可以让我在 Java 中定义 student_list
,这样它就不会像我目前观察到的那样导致 Whosebug
错误?
您观察到的 Whosebug 错误是由于构建器模式中的调用链造成的。您可以通过在静态初始化程序中添加一个变量来避免它:
public class FancyConstants {
public static final List<Person> student_list;
static {
ImmutableList.Builder<Person> builder = new ImmutableList.Builder<Person>();
builder.add(new Person("Amy",12,56));
builder.add(new Person("Tom",26,79));
.........
/* More similar definitions; could be very long */
builder.add(...);
student_list = builder.build();
}
}
显然,这不是很优雅,但它修复了 Stack Overflow 错误。
您可以通过从文件中读取数据来改进这种方法,该文件可以作为资源嵌入到您的 Java 程序中。
This Q&A 解释了如何从嵌入式资源中读取。由于您的程序拥有资源的内容,因此您可以使用少量代码填充 builder
,并且几乎没有错误检查。
要回答您原来的问题,您可以使用 -J
选项将 JVM 选项传递给 javac
。例如。我采用了您的代码模板,创建了 3600 次调用链,并使用 -J-Xss10m
.
javac
但是虽然这足以编译和 运行 程序(运行ning 不需要大的堆栈大小),但此源代码仍然会在 IDE 中引起问题或奇怪的行为,而这些问题不是配置为使用更大的堆栈大小处理此源代码。递归解析和处理源代码,太常见了。
此外,编译代码的大小接近方法大小限制,因此没有太多空间容纳更大的列表。所以我只能赞成