我刚刚在我们的生产环境中遇到了相当不愉快的经历 OutOfMemoryErrors: heapspace..
我将这个问题追溯到我ArrayList::new
在函数中的使用.
要通过声明的构造函数(t -> new ArrayList<>()
)验证这实际上比正常创建更糟糕,我编写了以下小方法:
public class TestMain {
public static void main(String[] args) {
boolean newMethod = false;
Map<Integer,List<Integer>> map = new HashMap<>();
int index = 0;
while(true){
if (newMethod) {
map.computeIfAbsent(index, ArrayList::new).add(index);
} else {
map.computeIfAbsent(index, i->new ArrayList<>()).add(index);
}
if (index++ % 100 == 0) {
System.out.println("Reached index "+index);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
运行方法newMethod=true;
将导致方法OutOfMemoryError
在索引达到30k后失败.随着newMethod=false;
程序不会失败,但一直冲击直到被杀(索引容易达到150万).
为什么在堆上ArrayList::new
创建如此多的Object[]
元素会导致OutOfMemoryError
如此之快?
(顺便说一下 - 当集合类型出现时也会发生HashSet …
我刚刚s
在下面的lambda表达式中替换为_
:
s -> Integer.parseInt(s)
Run Code Online (Sandbox Code Playgroud)
Eclipse编译器说:
'_'不应该用作标识符,因为它是源级别1.8的保留关键字.
我没有在JLS§3.9词汇结构/关键词中找到任何解释.
我想在java中创建一个包含键和值的列表,并决定创建类似的东西
private static HashMap<String, Set<String>> battleTanks = new HashMap<String, Set<String>>();
Run Code Online (Sandbox Code Playgroud)
然后我试图在那里添加一些像battleTanks.put("keytest1","valuetest1")的值
但它给了我一个错误
方法put(String,Set)在HashMap>类型中不适用于参数(String,String)
那么我该如何添加这些值呢?
在下面的示例中,我正在使用该字段,number
即使IntStream.range(0, 10).forEach(number -> new Thread(r).start());
它没有被使用。有没有办法重写它,以便我不必使用未使用的数字变量?
import javax.annotation.concurrent.NotThreadSafe;
import java.util.stream.IntStream;
public class LearnThreads {
public static void main(String[] args) {
UnsafeThreadClass counter = new UnsafeThreadClass();
Runnable r = () -> {
try {
System.out.println(counter.getValue() + " : Thread - " +Thread.currentThread());
} catch (InterruptedException e) {
e.printStackTrace();
}
};
IntStream.range(0, 10).forEach(number -> new Thread(r).start());
}
}
@NotThreadSafe
class UnsafeThreadClass {
private int value;
public synchronized int getValue() throws InterruptedException {
Thread.sleep(1000);
return value++;
}
}
Run Code Online (Sandbox Code Playgroud)