mirror of
https://github.com/wahyd4/pinpoint.git
synced 2026-08-20 18:25:55 +10:00
[강운덕] [LUCYSUS-1744] datasender의 메모리 할당 및 copy를 줄임. cl로드 구조 변경에 따른 TestCase 를 수정
git-svn-id: http://svn.bds.nhncorp.com/pe/hippo-tomcat-profiler/trunk@1453 84d0f5b1-2673-498c-a247-62c4ff18d310
This commit is contained in:
@@ -177,7 +177,7 @@ public class DefaultAgent implements Agent {
|
||||
}
|
||||
|
||||
private void initializeTraceContext() {
|
||||
this.traceContext = DefaultTraceContext.getTraceContext();
|
||||
this.traceContext = new DefaultTraceContext();
|
||||
|
||||
this.traceContext.setAgentId(this.agentId);
|
||||
this.traceContext.setApplicationId(this.applicationName);
|
||||
|
||||
@@ -14,6 +14,7 @@ import com.profiler.interceptor.bci.ByteCodeInstrumentor;
|
||||
import com.profiler.interceptor.bci.JavaAssistByteCodeInstrumentor;
|
||||
import com.profiler.modifier.ModifierRegistry;
|
||||
|
||||
@Deprecated
|
||||
public class TomcatProfiler {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(TomcatProfiler.class.getName());
|
||||
|
||||
@@ -23,17 +23,6 @@ public class DefaultTraceContext implements TraceContext {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(DefaultTraceContext.class.getName());
|
||||
|
||||
private static DefaultTraceContext CONTEXT = new DefaultTraceContext();
|
||||
|
||||
// initailze관련 생명주기가 뭔가 애매함. 추후 방안을 더 고려해보자.
|
||||
public static TraceContext initialize() {
|
||||
return CONTEXT = new DefaultTraceContext();
|
||||
}
|
||||
|
||||
// 얻는 것도 뭔가 모양이 마음에 안듬.
|
||||
public static DefaultTraceContext getTraceContext() {
|
||||
return CONTEXT;
|
||||
}
|
||||
|
||||
private final ThreadLocal<Trace> threadLocal = new NamedThreadLocal<Trace>("Trace");
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ public class HeaderTBaseSerializer {
|
||||
* This is the byte array that data is actually serialized into
|
||||
*/
|
||||
// udp 패킷 사이즈에 최대 맞춤.
|
||||
private final ByteArrayOutputStream baos_ = new ByteArrayOutputStream(1024 * 64);
|
||||
private final UnsafeByteArrayOutputStream baos_ = new UnsafeByteArrayOutputStream(1024 * 64);
|
||||
|
||||
/**
|
||||
* This transport wraps that byte array
|
||||
@@ -39,7 +39,6 @@ public class HeaderTBaseSerializer {
|
||||
*/
|
||||
public HeaderTBaseSerializer() {
|
||||
|
||||
// this(new TBinaryProtocol.Factory());
|
||||
this(new TCompactProtocol.Factory());
|
||||
}
|
||||
|
||||
@@ -65,7 +64,13 @@ public class HeaderTBaseSerializer {
|
||||
baos_.reset();
|
||||
writeHeader(header);
|
||||
base.write(protocol_);
|
||||
return baos_.toByteArray();
|
||||
// return baos_.toByteArray();
|
||||
return baos_.getInterBuffer();
|
||||
}
|
||||
|
||||
public int getInterBufferSize() {
|
||||
|
||||
return baos_.size();
|
||||
}
|
||||
|
||||
private void writeHeader(Header header) throws TException {
|
||||
|
||||
@@ -0,0 +1,186 @@
|
||||
package com.profiler.io;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class UnsafeByteArrayOutputStream extends OutputStream {
|
||||
|
||||
/**
|
||||
* The buffer where data is stored.
|
||||
*/
|
||||
protected byte buf[];
|
||||
|
||||
/**
|
||||
* The number of valid bytes in the buffer.
|
||||
*/
|
||||
protected int count;
|
||||
|
||||
/**
|
||||
* Creates a new byte array output stream. The buffer capacity is
|
||||
* initially 32 bytes, though its size increases if necessary.
|
||||
*/
|
||||
public UnsafeByteArrayOutputStream() {
|
||||
this(32);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new byte array output stream, with a buffer capacity of
|
||||
* the specified size, in bytes.
|
||||
*
|
||||
* @param size the initial size.
|
||||
* @throws IllegalArgumentException if size is negative.
|
||||
*/
|
||||
public UnsafeByteArrayOutputStream(int size) {
|
||||
if (size < 0) {
|
||||
throw new IllegalArgumentException("Negative initial size: "
|
||||
+ size);
|
||||
}
|
||||
buf = new byte[size];
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the specified byte to this byte array output stream.
|
||||
*
|
||||
* @param b the byte to be written.
|
||||
*/
|
||||
public void write(int b) {
|
||||
int newcount = count + 1;
|
||||
if (newcount > buf.length) {
|
||||
buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount));
|
||||
}
|
||||
buf[count] = (byte) b;
|
||||
count = newcount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes <code>len</code> bytes from the specified byte array
|
||||
* starting at offset <code>off</code> to this byte array output stream.
|
||||
*
|
||||
* @param b the data.
|
||||
* @param off the start offset in the data.
|
||||
* @param len the number of bytes to write.
|
||||
*/
|
||||
public void write(byte b[], int off, int len) {
|
||||
if ((off < 0) || (off > b.length) || (len < 0) ||
|
||||
((off + len) > b.length) || ((off + len) < 0)) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
} else if (len == 0) {
|
||||
return;
|
||||
}
|
||||
int newcount = count + len;
|
||||
if (newcount > buf.length) {
|
||||
buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount));
|
||||
}
|
||||
System.arraycopy(b, off, buf, count, len);
|
||||
count = newcount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the complete contents of this byte array output stream to
|
||||
* the specified output stream argument, as if by calling the output
|
||||
* stream's write method using <code>out.write(buf, 0, count)</code>.
|
||||
*
|
||||
* @param out the output stream to which to write the data.
|
||||
* @throws java.io.IOException if an I/O error occurs.
|
||||
*/
|
||||
public void writeTo(OutputStream out) throws IOException {
|
||||
out.write(buf, 0, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the <code>count</code> field of this byte array output
|
||||
* stream to zero, so that all currently accumulated output in the
|
||||
* output stream is discarded. The output stream can be used again,
|
||||
* reusing the already allocated buffer space.
|
||||
*
|
||||
* @see java.io.ByteArrayInputStream#count
|
||||
*/
|
||||
public void reset() {
|
||||
count = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a newly allocated byte array. Its size is the current
|
||||
* size of this output stream and the valid contents of the buffer
|
||||
* have been copied into it.
|
||||
*
|
||||
* @return the current contents of this output stream, as a byte array.
|
||||
* @see java.io.ByteArrayOutputStream#size()
|
||||
*/
|
||||
public byte toByteArray()[] {
|
||||
return Arrays.copyOf(buf, count);
|
||||
}
|
||||
|
||||
public byte[] getInterBuffer() {
|
||||
return buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current size of the buffer.
|
||||
*
|
||||
* @return the value of the <code>count</code> field, which is the number
|
||||
* of valid bytes in this output stream.
|
||||
* @see java.io.ByteArrayOutputStream#count
|
||||
*/
|
||||
public int size() {
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the buffer's contents into a string decoding bytes using the
|
||||
* platform's default character set. The length of the new <tt>String</tt>
|
||||
* is a function of the character set, and hence may not be equal to the
|
||||
* size of the buffer.
|
||||
* <p/>
|
||||
* <p> This method always replaces malformed-input and unmappable-character
|
||||
* sequences with the default replacement string for the platform's
|
||||
* default character set. The {@linkplain java.nio.charset.CharsetDecoder}
|
||||
* class should be used when more control over the decoding process is
|
||||
* required.
|
||||
*
|
||||
* @return String decoded from the buffer's contents.
|
||||
* @since JDK1.1
|
||||
*/
|
||||
public String toString() {
|
||||
return new String(buf, 0, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the buffer's contents into a string by decoding the bytes using
|
||||
* the specified {@link java.nio.charset.Charset charsetName}. The length of
|
||||
* the new <tt>String</tt> is a function of the charset, and hence may not be
|
||||
* equal to the length of the byte array.
|
||||
* <p/>
|
||||
* <p> This method always replaces malformed-input and unmappable-character
|
||||
* sequences with this charset's default replacement string. The {@link
|
||||
* java.nio.charset.CharsetDecoder} class should be used when more control
|
||||
* over the decoding process is required.
|
||||
*
|
||||
* @param charsetName the name of a supported
|
||||
* {@linkplain java.nio.charset.Charset </code>charset<code>}
|
||||
* @return String decoded from the buffer's contents.
|
||||
* @throws java.io.UnsupportedEncodingException
|
||||
* If the named charset is not supported
|
||||
* @since JDK1.1
|
||||
*/
|
||||
public String toString(String charsetName)
|
||||
throws UnsupportedEncodingException {
|
||||
return new String(buf, 0, count, charsetName);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Closing a <tt>ByteArrayOutputStream</tt> has no effect. The methods in
|
||||
* this class can be called after the stream has been closed without
|
||||
* generating an <tt>IOException</tt>.
|
||||
* <p/>
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,8 @@ public class UdpDataSender implements DataSender, Runnable {
|
||||
private int maxDrainSize = 10;
|
||||
// 주의 single thread용임
|
||||
private List<Object> drain = new ArrayList<Object>(maxDrainSize);
|
||||
// 주의 single thread용임
|
||||
private DatagramPacket reusePacket = new DatagramPacket(new byte[1], 1);
|
||||
|
||||
private DatagramSocket udpSocket = null;
|
||||
private Thread ioThread;
|
||||
@@ -44,10 +46,13 @@ public class UdpDataSender implements DataSender, Runnable {
|
||||
// 주의 single thread용임
|
||||
private HeaderTBaseSerializer serializer = new HeaderTBaseSerializer();
|
||||
|
||||
|
||||
private AtomicBoolean allowInput = new AtomicBoolean();
|
||||
|
||||
public UdpDataSender(String host, int port) {
|
||||
Assert.notNull(host, "host must not be null");
|
||||
if (host == null ) {
|
||||
throw new NullPointerException("host must not be null");
|
||||
}
|
||||
|
||||
// Socket 생성에 에러가 발생하면 Agent start가 안되게 변경.
|
||||
this.udpSocket = createSocket(host, port);
|
||||
@@ -69,7 +74,8 @@ public class UdpDataSender implements DataSender, Runnable {
|
||||
|
||||
private DatagramSocket createSocket(String host, int port) {
|
||||
try {
|
||||
DatagramSocket datagramSocket = new DatagramSocket();
|
||||
DatagramSocket datagramSocket = new DatagramSocket();
|
||||
|
||||
datagramSocket.setSoTimeout(1000 * 5);
|
||||
|
||||
InetSocketAddress serverAddress = new InetSocketAddress(host, port);
|
||||
@@ -169,6 +175,8 @@ public class UdpDataSender implements DataSender, Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void sendPacket(Object dto) {
|
||||
TBase<?, ?> tBase;
|
||||
if (dto instanceof TBase) {
|
||||
@@ -179,15 +187,16 @@ public class UdpDataSender implements DataSender, Runnable {
|
||||
logger.warn("sendPacket fail. invalid type:" + dto.getClass());
|
||||
return;
|
||||
}
|
||||
// TODO single thread이므로 데이터 array를 nocopy해서 보낼수 있음.
|
||||
byte[] sendData = serialize(tBase);
|
||||
if (sendData == null) {
|
||||
logger.warn("sendData is null");
|
||||
// single thread이므로 데이터 array를 nocopy해서 보냄.
|
||||
byte[] interBufferData = serialize(tBase);
|
||||
int interBufferSize = serializer.getInterBufferSize();
|
||||
if (interBufferData == null) {
|
||||
logger.warn("interBufferData is null");
|
||||
return;
|
||||
}
|
||||
DatagramPacket packet = new DatagramPacket(sendData, sendData.length);
|
||||
reusePacket.setData(interBufferData, 0, interBufferSize);
|
||||
try {
|
||||
udpSocket.send(packet);
|
||||
udpSocket.send(reusePacket);
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Data sent. " + dto);
|
||||
}
|
||||
@@ -229,6 +238,10 @@ public class UdpDataSender implements DataSender, Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
private int beforeSerializeLength() {
|
||||
return serializer.getInterBufferSize();
|
||||
}
|
||||
|
||||
private Header headerLookup(TBase<?, ?> dto) throws TException {
|
||||
// header 객체 생성을 안하고 정적 lookup이 되도록 변경.
|
||||
return locator.headerLookup(dto);
|
||||
|
||||
Reference in New Issue
Block a user