psz*_*kov 5 java caching garbage-collection
目前我正在改变我的心态,开发更多缓存友好的应用程序.
在C++中我可以使用堆栈分配,我也可以在一个数组(数据驱动编程)等中保存相同的数据...
但是我也是Java开发人员并且有一个问题:
我听说Java是"缓存错过发电机".
所有东西都在堆中,并在分配或垃圾收集器工作后分散在整个RAM中.我认为同样的问题是C#.
以数据驱动方式编写Java是否有意义?
有没有什么方法可以优化Java代码,或者我们仍然坚持Java自动优化和缓存未命中?
在C++中我可以使用堆栈分配,也可以在一个数组(数据驱动编程)等中保存具有相同目的的数据...
在Java中,它将使用Escape Analysis自动在堆栈上放置短暂的对象.我不担心这个,除非你在分析器中看到这是一个问题.即便如此,分析器可能会阻止逃逸分析工作,这在实际程序中不是问题.
我听说Java是"缓存未命中生成器".
Java比使用嵌入在对象中的结构或对象编写的C++或C#代码具有更多的引用.这有多大差异取决于您的应用程序对微调的敏感程度.
所有东西都在堆中,并在分配或垃圾收集器工作后分散在整个RAM中.我认为同样的问题是C#.
Java(和C#)也不是随机内存安排程序.理论上,物体可以在任何地方,但在实践中它们通常不是.考虑一下你是否有;
class A { }
class B {
A a = new A();
}
Run Code Online (Sandbox Code Playgroud)
如果你创建一个B,A可以在任何地方,但通常不是.当Java在Eden空间中分配内存时,它通常在内存中是连续的.这是分配内存的最简单,最有效的方法.这意味着99.9%的时间A将在紧接着之后B,可能在同一缓存行上.事实上,对于某些用例,"虚假共享"是Java中的一个真正问题.即当你想要两个不在同一缓存行上的对象时.
GC上会发生什么?
在OpenJDK/Oracle JVM中,以与发现相反的顺序复制对象.即在大多数情况下A会立即出现B.
以数据驱动方式编写Java是否有意义?
情况属实,在<1%的情况下,这可能会产生很大的不同.但是,对于大多数代码而言,如果不是大多数应用程序,那么您将需要担心更多更大的问题.
有没有什么方法可以优化Java代码,或者我们仍然坚持Java自动优化和缓存未命中?
您可以使用它Unsafe来控制您选择的内存结构.我们(Chronicle Software)拥有允许您这样做的库,但即使我们希望您使用我们的服务,在99%的情况下,没有充分的理由担心这种微调.只有在极端情况下才能产生任何真正的不同.
我不想修改垃圾收集器.但我知道它复制了所有的东西所以它有点混乱结构.我想尽可能地避免这种情况.
这就是GC的作用.它将相关对象打包在一起,不仅仅是为了提高效率,而是因为以找到它们的方式复制对象是最简单的实现.如果你想要的话,随机排列数据是你必须要刻意做的事情,这将是更多的工作.例如,如果你想避免"虚假分享",这是非常重要的.