You cannot, the address of sa escapes to the heap because it is returned to the caller. The solution may be to refactor the method to take a *syscall.SockaddrInet4 that was allocated in the caller, but that is not something that can be done as a consumer of the net package.
On Tuesday, 2 August 2016 18:21:35 UTC+10, Михаил Монашёв wrote: > > Hi, golang-nuts. > > I'm trying to speed up my app, and deleted all of memory allocation > from my code. But how to prevent memory allocation here? > > > ROUTINE ======================== net.ipToSockaddr in > C:/Go/src/net/ipsock_posix.go > 516093 516093 (flat, cum) 24.33% of Total > . . 166: } > . . 167: ip4 := ip.To4() > . . 168: if ip4 == nil { > . . 169: return nil, > &AddrError{Err: "non-IPv4 address", Addr: ip.String()} > . . 170: } > 516093 516093 171: sa := &syscall.SockaddrInet4{Port: > port} > . . 172: copy(sa.Addr[:], ip4) > . . 173: return sa, nil > . . 174: case syscall.AF_INET6: > . . 175: // In general, an IP wildcard > address, which is either > . . 176: // "0.0.0.0" or "::", means the > entire IP addressing > ROUTINE ======================== syscall.(*RawSockaddrAny).Sockaddr in > C:/Go/src/syscall/syscall_windows.go > 516158 516158 (flat, cum) 24.33% of Total > . . 678: case AF_UNIX: > . . 679: return nil, EWINDOWS > . . 680: > . . 681: case AF_INET: > . . 682: pp := > (*RawSockaddrInet4)(unsafe.Pointer(rsa)) > 516158 516158 683: sa := new(SockaddrInet4) > . . 684: p := > (*[2]byte)(unsafe.Pointer(&pp.Port)) > . . 685: sa.Port = int(p[0])<<8 + int(p[1]) > . . 686: for i := 0; i < len(sa.Addr); i++ > { > . . 687: sa.Addr[i] = pp.Addr[i] > . . 688: } > ROUTINE ======================== net.(*UDPConn).readFrom in > C:/Go/src/net/udpsock_posix.go > 516028 1168218 (flat, cum) 55.07% of Total > . . 38: return ipToSockaddr(family, a.IP, a.Port, > a.Zone) > . . 39:} > . . 40: > . . 41:func (c *UDPConn) readFrom(b []byte) (int, > *UDPAddr, error) { > . . 42: var addr *UDPAddr > . 652190 43: n, sa, err := c.fd.readFrom(b) > . . 44: switch sa := sa.(type) { > . . 45: case *syscall.SockaddrInet4: > 516028 516028 46: addr = &UDPAddr{IP: sa.Addr[0:], > Port: sa.Port} > . . 47: case *syscall.SockaddrInet6: > . . 48: addr = &UDPAddr{IP: sa.Addr[0:], > Port: sa.Port, Zone: zoneToString(int(sa.ZoneId))} > . . 49: } > . . 50: return n, addr, err > . . 51:} > Total: 2121170 > ROUTINE ======================== syscall.WSARecv in > C:/Go/src/syscall/zsyscall_windows.go > 122693 122695 (flat, cum) 5.78% of Total > . . 1515: Syscall9(procGetAcceptExSockaddrs.Addr(), > 8, uintptr(unsafe.Pointer(buf)), uintptr(rxdatalen), > uintptr(laddrlen), uintptr(raddrlen), uintptr(unsafe.Pointer(lrsa)), > uintptr(unsafe.Pointer(lrsalen)), uintptr(unsafe.Pointer > (rrsa)), uintptr(unsafe.Pointer(rrsalen)), 0) > . . 1516: return > . . 1517:} > . . 1518: > . . 1519:func WSARecv(s Handle, bufs *WSABuf, bufcnt > uint32, recvd *uint32, flags *uint32, overlapped *Ove > rlapped, croutine *byte) (err error) { > . 2 1520: r1, _, e1 := Syscall9(procWSARecv.Addr(), > 7, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintpt > r(bufcnt), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(flags)), > uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe > .Pointer(croutine)), 0, 0) > . . 1521: if r1 == socket_error { > . . 1522: if e1 != 0 { > 122693 122693 1523: err = error(e1) > . . 1524: } else { > . . 1525: err = EINVAL > . . 1526: } > . . 1527: } > . . 1528: return > ROUTINE ======================== syscall.WSARecvFrom in > C:/Go/src/syscall/zsyscall_windows.go > 135757 135757 (flat, cum) 6.40% of Total > . . 1542: > . . 1543:func WSARecvFrom(s Handle, bufs *WSABuf, > bufcnt uint32, recvd *uint32, flags *uint32, from *RawSo > ckaddrAny, fromlen *int32, overlapped *Overlapped, croutine *byte) (err > error) { > . . 1544: r1, _, e1 := > Syscall9(procWSARecvFrom.Addr(), 9, uintptr(s), > uintptr(unsafe.Pointer(bufs)), ui > ntptr(bufcnt), uintptr(unsafe.Pointer(recvd)), > uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(from)), > uintptr(unsafe.P > ointer(fromlen)), uintptr(unsafe.Pointer(overlapped)), > uintptr(unsafe.Pointer(croutine))) > . . 1545: if r1 == socket_error { > . . 1546: if e1 != 0 { > 135757 135757 1547: err = error(e1) > . . 1548: } else { > . . 1549: err = EINVAL > . . 1550: } > . . 1551: } > . . 1552: return > > > -- > > Michael > > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.