我想雇用 package test.thread;
import java.util.List;
import java.util.Scanner;
public class Producer implements Runnable {
private List<String> jobs = null;
public Producer(List<String> jobs) {
this.jobs = jobs;
}
@Override
public void run() {
System.out.println("Starting Producer");
while(true)
{
synchronized (jobs) {
try {
if (jobs.isEmpty()) {
System.out.println("Please provide the job details: ");
Scanner scanner = new Scanner(System.in);
String job = scanner.nextLine();
jobs.add(job);
scanner.close();
jobs.notifyAll();
Thread.sleep(4000);
} else {
jobs.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
package test.thread;
import java.util.List;
public class Consumer implements Runnable {
private List<String> jobs = null;
public Consumer(List<String> list) {
this.jobs = list;
}
@Override
public void run() {
while(true)
{
synchronized (jobs) {
try {
if (jobs.isEmpty()) {
jobs.wait();
} else {
for (String job : jobs) {
System.out.println("Job completed: " + job);
jobs.remove(job);
Thread.sleep(2000);
}
jobs.notifyAll();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
package test.thread;
import java.util.ArrayList;
import java.util.List;
public class TestThread {
public static void main(String...strings )
{
List<String> list = new ArrayList<String>();
Producer producer = new Producer(list);
Consumer consumer = new Consumer(list);
Thread prodThread = new Thread(producer, "producer");
Thread consThread = new Thread(consumer, "consumer");
prodThread.start();
consThread.start();
}
}
来做这样的事情:
com.sun.management.ThreadMXBean
问题是,此方法实际返回了什么:在方法调用时分配的新内存量或分配对象的大小?要明确我的意思是什么:
1)假设我在long before = threadMxBean.getThreadAllocatedBytes(currentThreadId);
seriousBusiness(); // some calls here
long after = threadMxBean.getThreadAllocatedBytes(currentThreadId);
long allocDiff = after - before; // use for stats or whatever
调用中分配了一个巨大的数组,因此为此目的分配了一个新的内存区域,seriousBusiness()
增加了相应的值。
2)一段时间过去了,有一次GC运行,收集了未使用的数组,现在内存区域是免费的。
3)我再次做一些调用(在同一个线程中),JVM发现它不需要分配新内存并重新使用该内存区域以达到新的目的,这导致getThreadAllocatedBytes
值不增长
我可能不确切知道JVM内存管理是如何工作的,但问题应该是清楚的。
另外,如果第一个假设是正确的(只是新的内存分配计数),那么进行getThreadAllocatedBytes
测量的正确方法是什么?
UPD。我试着检查一下自己:http://pastebin.com/ECQpz8g4。 (在代码中睡觉是为了允许我用JMC连接到JVM)。
TL; DR:分配一个巨大的int数组,然后分配GC,然后分配一些新对象并检查分配的内存。这就是我得到的:
所以,看起来GC实际上是运行的,虽然内存肯定被分配并随后被释放,但我得到了这个输出:
per-thread object allocations / memory footprint
所以,我只是在等待有JVM内存专业知识的人告诉我,我是对的还是我错了。
答案 0 :(得分:2)
ThreadMXBean.getThreadAllocatedBytes
返回给定线程从头开始分配的累积堆内存量,即这是一个单调递增的计数器。它大致是分配对象的总大小。
修改强>
没有&#39;线程所有权&#39; HotSpot JVM中分配的堆内存。分配内存后,它将在所有线程之间共享。所以,&#39;每线程使用&#39;没有意义;当JVM在堆中分配对象时,它不知道此内存是否已在之前和之后使用过。
答案 1 :(得分:2)
引用ThreadMXBean,它代表目标线程报告堆中分配的字节数,但暗示这相当于分配的对象的大小。但有一点需要注意:
返回值是近似值,因为某些Java虚拟 机器实现可以使用对象分配机制 导致分配对象的时间和时间之间的延迟 其大小记录
因此,我认为堆空间的回收对报告的值没有影响,因为它只报告分配的绝对字节数,因此如果分配100个字节,则回收80个字节,然后分配另外100个字节,这些事件结束时报告的(delta)值将是200个字节,尽管 net 分配只有120个。